釋出:人在現場那一路的根目錄解析帶上文件記載的預設值 #23
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jsc-assist",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
|
||||
"skills": "./skills",
|
||||
"author": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jsc-assist",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
|
||||
"skills": "./skills",
|
||||
"jsc": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jsc-assist",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
|
||||
"skills": "./skills/",
|
||||
"jsc": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -24,17 +24,21 @@ The root comes from outside this skill. `schedule.sh` resolves it while a person
|
||||
| Who invoked this round | Where `{CURRENT}` comes from |
|
||||
| --- | --- |
|
||||
| the schedule — an unattended round, the `patrol` whose trigger is 排程 | the path after `工具根目錄=` in the invocation text, taken verbatim. No command is run |
|
||||
| a person, in front of the terminal | the same token when the invocation carries one; otherwise `readlink -f "$JSC_HOME/current"`, run once |
|
||||
| a person, in front of the terminal | the same token when the invocation carries one; otherwise `readlink -f "${JSC_HOME:-$HOME/.jsc}/current"`, run once |
|
||||
|
||||
**An unattended round that finds no root in its invocation stops there.** Report that the scheduled entry carries no `工具根目錄=` — an entry written by an older `schedule.sh` — say the fix is to run `start` again, or `jsc-assist/tools/schedule.sh install patrol` under `$JSC_HOME/current`, so the entry is rewritten with the root in it. Then take the operation's `aborted` status, write the `skill-end`, and stop.
|
||||
|
||||
Never work the root out instead. `readlink -f "$JSC_HOME/current"`, `ls -d "$JSC_HOME/current"` and every other resolve are refused in an unattended session — measured, see the table below — so running one does not produce a root, it produces a round that stops one step earlier having recorded nothing. Never fall back to `$JSC_HOME/current` as a written-out path either, never take a path from the plugin prompt or a previous transcript, and never guess.
|
||||
Never work the root out instead. `readlink -f "${JSC_HOME:-$HOME/.jsc}/current"`, `ls -d "$JSC_HOME/current"` and every other resolve are refused in an unattended session — measured, see the table below — so running one does not produce a root, it produces a round that stops one step earlier having recorded nothing. Never fall back to `$JSC_HOME/current` as a written-out path either, never take a path from the plugin prompt or a previous transcript, and never guess.
|
||||
|
||||
**Only an attended invocation may resolve the root itself.** `readlink -f "$JSC_HOME/current"` covers the documented `~/.jsc` fallback in the same call and prints one literal absolute path. It raises one permission prompt, and a person is there to answer it once. That is the whole reason the branch exists: portability survives where somebody can approve it, and nowhere else.
|
||||
**Only an attended invocation may resolve the root itself.** `readlink -f "${JSC_HOME:-$HOME/.jsc}/current"` prints one literal absolute path. It raises one permission prompt, and a person is there to answer it once. That is the whole reason the branch exists: portability survives where somebody can approve it, and nowhere else.
|
||||
|
||||
**The `:-$HOME/.jsc` half is load-bearing, and dropping it is how this line was wrong before.** `$JSC_HOME` is documented as defaulting to `~/.jsc`, and the shell does not know that: with the variable unset, a bare `$JSC_HOME/current` expands to `/current`, which is not a fallback to anything. Write the default into the expansion or the documented default never happens.
|
||||
|
||||
Take the root once per invocation and reuse that one answer. Never resolve it again per call, never print it as a report line of its own, and never add a tool that prints it. Never test the root with a command either — an unattended round cannot, and the first script call is the test that matters anyway.
|
||||
|
||||
An empty token, an empty `readlink` result, a path that is not absolute, or a resolved path that is not an existing directory means there is no root to work with. **That fourth item is the one the other three wave through.** With `JSC_HOME` unset, `readlink -f "$JSC_HOME/current"` prints `/current` and exits 0 — non-empty, absolute, and past every other item — and each literal path built from it then names a place that is not there. So the attended resolve is only accepted once `[ -d "{the path just printed}" ]` says that directory exists, run in the same approved step as the resolve itself. The unattended round tests nothing, exactly as above: its root was written into the entry by whoever installed the schedule, and its first script call is what fails if that root is wrong. Report it, say `jsc-cli:deploy` has to run, take the operation's `aborted` status, and stop. Never fall back to a cache path, and never create the root here. Completion condition: one literal absolute path is in hand and every later command line carries it, or the missing root was reported and the operation stopped.
|
||||
An empty token, an empty `readlink` result, a path that is not absolute, or a resolved path that is not an existing directory means there is no root to work with. **That fourth item is the one the other three wave through**, so the attended resolve is only accepted once `[ -d "{the path just printed}" ]` says that directory exists, run in the same approved step as the resolve itself. It stays a separate check even now that the expansion carries its own default, because the ways a resolve can print a plausible path that is not there do not end with an unset variable: `JSC_HOME` set to a directory that no longer exists, `HOME` unset in a stripped environment, or the link farm simply never deployed all reach this line with something absolute in hand.
|
||||
|
||||
**How that guard earned its place is worth keeping.** This step used to resolve a bare `$JSC_HOME/current`, and on a machine that had never set `JSC_HOME` — the documented default being `~/.jsc` — it printed `/current` and exited 0: non-empty, absolute, and past every other item. The directory check was the only thing that caught it, and it caught it while pointing at the wrong culprit, because a resolve that cannot be trusted looks exactly like a root that is not there. The expansion above is the fix; this check is what noticed. The unattended round tests nothing, exactly as above: its root was written into the entry by whoever installed the schedule, and its first script call is what fails if that root is wrong. Report it, say `jsc-cli:deploy` has to run, take the operation's `aborted` status, and stop. Never fall back to a cache path, and never create the root here. Completion condition: one literal absolute path is in hand and every later command line carries it, or the missing root was reported and the operation stopped.
|
||||
|
||||
## Every script call carries a literal absolute path
|
||||
|
||||
@@ -57,6 +61,8 @@ The reason is the permission layer: it matches its rules against the command tex
|
||||
|
||||
A literal allow rule that itself starts with `$JSC_HOME` was added to the settings file and the same call was still refused, so no permission rule makes the variable form work either. The literal path is the whole fix, on both sides.
|
||||
|
||||
Row 4 was measured before the resolve carried its own default, and the verdict is the same for `readlink -f "${JSC_HOME:-$HOME/.jsc}/current"`: the rule is matched against the text as written, and that text still holds variables. The default fixed which path the resolve produces, not whether an unattended round may run it — that round still gets its root handed in, and this line stays the attended branch only.
|
||||
|
||||
**These rules outrank portability, and the next maintainer is the one who has to know why.** A variable in the path reads as the portable choice and costs nothing while a person is watching: the prompt appears, somebody approves it, the round carries on. The scheduled round has nobody to approve it. It stops at its first script call, records nothing, writes no heartbeat, and the machine then reads as a stopped assistant with no trace of the refusal anywhere. And the resolve is no way out of that, because row 4 of the table is the resolve itself: a round that cannot run a script cannot run the command that would have told it which script to run. That is why the root is handed in by whoever installed the schedule, and why anything written into a command line here is already literal.
|
||||
|
||||
## Tool paths
|
||||
|
||||
Reference in New Issue
Block a user