Merge develop

三份 manifest 取分支上的較高版號:develop 那邊到 0.3.6,這條分支本來就是為了
讓開那一號才升到 0.3.7,取低的等於把版號往回退。

行為清單第 10 行兩邊各改了同一行的不同地方,合起來留:develop 加的是委派
清單檢核多判一種填錯的 probe、以及修法要回該技能的存取庫核對過再改寫;這條
分支加的是第一組多跑一項腳本路徑檢查。兩件事互不相干,取任一邊都會弄丟另
一邊。外部呼叫那一行 develop 沒動過,直接取分支上的。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 11:29:00 +08:00
co-authored by Claude Opus 5
9 changed files with 209 additions and 78 deletions
+4 -4
View File
@@ -23,9 +23,9 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
6. Run the two wiki-rule checkers once each, not per domain — both judge shared rules, so a second run adds nothing:
- `jsc-gitea/tools/check-wiki-rules.sh`, which verifies wiki repo resolution and the `hash-id` rule for every page type. It takes no argument. Route each exit code: 0 — printed `OK` on stdout, every item passed; 1 — the first mismatch is printed on stderr as `{項目}: want=… got=…` and the script stops there, so report that item and rerun after the fix, because the remaining items were never reached. Those are its only two codes. Until this audit, no flow in the whole repository ever called it.
- `tools/check-page-name.sh {root}`, where `{root}` is the directory holding the domain repos — the parent directory of the paths `tools/sync-domains.sh` printed in step 1, so no extra derivation is needed. It compares the page-name pattern in its three copies: `jsc-gitea/tools/page-name.sh` (the canonical one), `jsc-hooks/hooks/comment-scope.sh` and `jsc-log/tools/worklog-pending.sh`. Route each exit code: 0 — the three agree; 1 — the mismatches are printed on stderr as `{檔案}:{說明}`, so report each one as a compliance failure, and a copy that could not be found is one of those lines; 2 — usage error, the tool takes exactly one argument; 3 — none of the three copies was found, so the root is wrong: fix it and rerun. Record exit 3 as 「什麼都沒查」; it is **never** a pass. The three copies stay separate on purpose — a hook must be self-contained and may not depend on another plugin's path at run time — so consistency is checked here instead of shared in a function.
7. Run `tools/check-delegate.sh {root}` once for the whole round, with the same `{root}` item 6 passed to `check-page-name.sh`. It compares the delegation list `tools/delegate-spec.tsv` against the skills `tools/list-skills.sh` finds on this machine: one skill one row, eleven columns, every mandatory column filled, and every `next` naming a skill that exists. It belongs in group 1 for the same reason `ste100-lint.sh` does — it is a deterministic script verdict, and it is judged **once for the whole round** rather than per domain, because the list is a single file covering every domain. Handing it to the group 2 sub agents would have ten agents run the same script over the same file and report ten copies of the same lines, with no single verdict anywhere; handing it to group 3 would turn a pass-or-fail check into a suggestion. Route each exit code:
- 0 — the list and the machine's skills correspond one to one and every mandatory column is filled. **A run that printed lines on stdout and exited 0 passed.** Those lines are hints, not compliance failures, and they are printed on stdout precisely so they are told apart from the failures on stderr: `origin=seed` marks a row seeded from the earlier inventory that has not been through the decision tree yet, and a version-behind line marks a row whose recorded `version` trails its domain's current one. The version number is per domain, so one skill's change marks every other skill of that domain — counting those as failures paints whole domains red on every release, and the hint stops being read at all. Report the hint count and the rows, and open no decision-tree item for them.
- 1 — a missing row, a duplicate row, a row for a skill this machine does not have, an empty column, a column value outside its vocabulary, or a `next` naming a skill that does not exist. Every one is printed on stderr as `{清單路徑}:{domain}/{技能名}:{說明}`. Report each as a compliance failure, named by the skill it belongs to. A missing row means the assistant is blind to that skill; an extra row means it will trigger a skill that cannot be called, and a failing trigger retries instead of pausing.
7. Run `tools/check-delegate.sh {root}` once for the whole round, with the same `{root}` item 6 passed to `check-page-name.sh`. It compares the delegation list `tools/delegate-spec.tsv` against the skills `tools/list-skills.sh` finds on this machine: one skill one row, twelve columns, every mandatory column filled, every `next` naming a skill that exists, and every `probe` either a runnable read-only command, a `pending:{reason}`, or a `-` on the rows that take one. It belongs in group 1 for the same reason `ste100-lint.sh` does — it is a deterministic script verdict, and it is judged **once for the whole round** rather than per domain, because the list is a single file covering every domain. Handing it to the group 2 sub agents would have ten agents run the same script over the same file and report ten copies of the same lines, with no single verdict anywhere; handing it to group 3 would turn a pass-or-fail check into a suggestion. Route each exit code:
- 0 — the list and the machine's skills correspond one to one and every mandatory column is filled. **A run that printed lines on stdout and exited 0 passed.** Those lines are hints, not compliance failures, and they are printed on stdout precisely so they are told apart from the failures on stderr: `origin=seed` marks a row seeded from the earlier inventory that has not been through the decision tree yet, a version-behind line marks a row whose recorded `version` trails its domain's current one, a `probe=pending:` line marks a delegated slice whose read-only entry point is not wired yet, and a line saying a `probe` domain is not installed here marks a script this machine cannot check. The version number is per domain, so one skill's change marks every other skill of that domain — counting those as failures paints whole domains red on every release, and the hint stops being read at all. Report the hint count and the rows, and open no decision-tree item for them.
- 1 — a missing row, a duplicate row, a row for a skill this machine does not have, an empty column, a column value outside its vocabulary, a `next` naming a skill that does not exist, or a `probe` in the wrong shape — a command on a row whose `way` holds `invoke`, a `-` on a row whose `way` holds only `patrol` or `remind`, a dollar sign or tilde, an unknown substitution point, or a script that does not exist. Every one is printed on stderr as `{清單路徑}:{domain}/{技能名}:{說明}`. Report each as a compliance failure, named by the skill it belongs to. A missing row means the assistant is blind to that skill; an extra row means it will trigger a skill that cannot be called, and a failing trigger retries instead of pausing. A wrong `probe` fails every unattended round in the same silent way, and the command-on-an-`invoke`-row case is worse than a failure: the assistant runs a bare script where the whole skill was supposed to run, and the round looks clean.
- 2 — usage error: the script takes at most one argument. Fix the call and rerun; this is a defect in this skill, not a finding about the skill set.
- 3 — nothing was checked, because `tools/delegate-spec.tsv` is missing, the root could not be derived, or `list-skills.sh` listed no skill. Record it as 「無委派清單可查」 with the cause from stderr and carry it into the step 3 merge; **exit 3 is never a pass**, because a check that read nothing reports neither a missing row nor an extra one.
@@ -86,7 +86,7 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
- Optimization options: apply / defer / custom. Record the chosen option in the finding's 決議 field as `套用`, `延後` or `自訂`, and today's date in 決議日期. Any suggestion that weakens a protection must name the protection it removes and must not be applied unless the user explicitly accepts that tradeoff. Cost optimization may move, merge, cache, or narrow checks; it must not delete a compliance check only because it is expensive.
Completion condition: every domain's checklist is complete after the merge, with the two whole-round verdicts carrying the same value in every domain, and every compliance failure and every optimization finding has a recorded decision — every optimization finding carrying both 決議 and 決議日期.
4. Apply the confirmed fixes and accepted optimizations — the file-change part MUST run as a sub agent, one sub agent per affected domain repo, and those sub agents run **in parallel**: each repo's files are independent. A fix that changes a skill's behavior also updates that skill's `## {name}` section in the same repo's `references/behaviors.md`, in the same pass, so the fix and the behavior list land in one PR. A confirmed `check-delegate.sh` fix is written by the **main agent**, never by the per-repo sub agents: `tools/delegate-spec.tsv` is one file for the whole skill set, and parallel agents writing one file overwrite each other's rows. A missing row is filled by running the decision tree of [`../../references/delegate-criteria.md`](../../references/delegate-criteria.md) for that skill through `jsc-ask:ask` and writing the answer as a row with `origin` set to `judged`; an extra row is deleted; a dead `next` is repointed at a skill that exists. A fix that changed a skill's behavior in this same round also re-judges that skill and moves its row's `version`. Then run `tools/sync-skill-manifest.sh {domain-path}` directly (no sub agent needed) for each affected domain repo to refresh that domain README's 「Skills 目錄」 section and bump the version in all three manifests. Route each exit code: 0 — the README block and all three manifests are synced; 1 — the domain path, `skills/`, `README.md`, the `JSC-SKILLS` markers, a `SKILL.md`, a manifest, or a manifest `version` field is missing, so fix the named cause on stderr and rerun; 2 — usage error, the script takes exactly one argument; any other code — the script runs under `set -e`, so treat it as an environment fault and stop, never as a successful sync. Completion condition: every affected repo carries the changes, the matching `references/behaviors.md` update for every fix that changed a skill's behavior, the `tools/delegate-spec.tsv` rows for every accepted delegation fix, and the manifest bump.
4. Apply the confirmed fixes and accepted optimizations — the file-change part MUST run as a sub agent, one sub agent per affected domain repo, and those sub agents run **in parallel**: each repo's files are independent. A fix that changes a skill's behavior also updates that skill's `## {name}` section in the same repo's `references/behaviors.md`, in the same pass, so the fix and the behavior list land in one PR. A confirmed `check-delegate.sh` fix is written by the **main agent**, never by the per-repo sub agents: `tools/delegate-spec.tsv` is one file for the whole skill set, and parallel agents writing one file overwrite each other's rows. A missing row is filled by running the decision tree of [`../../references/delegate-criteria.md`](../../references/delegate-criteria.md) for that skill through `jsc-ask:ask` and writing the answer as a row with `origin` set to `judged`; an extra row is deleted; a dead `next` is repointed at a skill that exists; a wrong `probe` is rewritten per that same file — verified against the owning repo, not guessed — and set to `pending:{reason}` when the slice has no read-only entry point on this machine. A fix that changed a skill's behavior in this same round also re-judges that skill and moves its row's `version`. Then run `tools/sync-skill-manifest.sh {domain-path}` directly (no sub agent needed) for each affected domain repo to refresh that domain README's 「Skills 目錄」 section and bump the version in all three manifests. Route each exit code: 0 — the README block and all three manifests are synced; 1 — the domain path, `skills/`, `README.md`, the `JSC-SKILLS` markers, a `SKILL.md`, a manifest, or a manifest `version` field is missing, so fix the named cause on stderr and rerun; 2 — usage error, the script takes exactly one argument; any other code — the script runs under `set -e`, so treat it as an environment fault and stop, never as a successful sync. Completion condition: every affected repo carries the changes, the matching `references/behaviors.md` update for every fix that changed a skill's behavior, the `tools/delegate-spec.tsv` rows for every accepted delegation fix, and the manifest bump.
5. Sync the canonical marketplace — a **required** step, never optional. The canonical pair lives in `plugins/meta` and every domain repo carries a byte-identical copy, so a fix that leaves the copies apart makes some repos register a stale plugin set. Run `tools/sync-marketplace.sh {domain} {repo-url} {description}` once with an existing entry's own current values (rewriting the same entry is idempotent); the script rewrites both canonical files and copies them into every domain repo. Route each exit code:
- Exit 3 — written, but some domain repo is not present locally. Run `tools/sync-domains.sh`, then rerun this step.
- Exit 2 — usage error: the script takes exactly three arguments. Fix them and rerun.