feat(m2): expose status and daily tools through jobbsok-tools
This commit is contained in:
parent
bdb6291042
commit
c7db9f16a0
4 changed files with 578 additions and 19 deletions
|
|
@ -44,11 +44,31 @@ Two environment variables, and they are NOT the same one:
|
|||
spelling problem above: a Windows adopter setting it
|
||||
merely to say `python` would serve without the guard.
|
||||
|
||||
The gate is on the VERSION, not on the guard being importable. That is the
|
||||
shell version's semantics carried over unchanged, and it is a known weakness
|
||||
(O4 in docs/cowork-probe.md): `selvsjekk` can report `guard_versjon: null`
|
||||
while the server runs happily. It is harmless while nothing writes and becomes
|
||||
a defect in M2. Fixing it is an M2 decision, not a porting one.
|
||||
Two gates, in this order (O4, decided in docs/cowork-probe.md and implemented
|
||||
at plan Step 24):
|
||||
|
||||
1. VERSION. The interpreter reports at least 3.10, or it is not used.
|
||||
2. THE GUARD. The interpreter can import `llm_ingestion_guard`, or the
|
||||
launcher refuses to serve at all and says which command installs it.
|
||||
|
||||
Until M2 there was only the first, and the measured consequence is the reason
|
||||
for the second: the M1 probe found the server running happily on the host's
|
||||
3.14.0 with `selvsjekk` reporting `guard_versjon: null`, because nothing had
|
||||
ever asked. That cost nothing while no tool wrote anything. From M2 the case
|
||||
folder and the decision log persist employer names, titles, URLs and notes
|
||||
that came out of a listing, and the guard is the boundary those writes are
|
||||
supposed to cross.
|
||||
|
||||
Refusing is cheap here, and that is the deciding argument rather than a
|
||||
consolation: every skill in this plugin degrades to manual paste with
|
||||
`jobbsok-tools` absent. A launcher that refuses removes a connector; it does
|
||||
not strand the operator. Failing open would persist untrusted text through the
|
||||
one boundary this plugin exists to hold.
|
||||
|
||||
The guard gate costs one extra interpreter start-up at launch, which is paid
|
||||
once per session against Cowork's MCP start-up timeout. It is a real cost and
|
||||
it is worth naming; it is not a reason to check something cheaper that answers
|
||||
a different question.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
|
@ -118,6 +138,25 @@ def version_ok(tolk):
|
|||
)
|
||||
|
||||
|
||||
#: The ingestion guard, by the name the interpreter has to be able to import.
|
||||
#: build-brief calls this the trust boundary, and the boundary is the write.
|
||||
GUARD_MODUL = "llm_ingestion_guard"
|
||||
|
||||
#: What fixes a failed guard gate. Named in the refusal, because a refusal
|
||||
#: that does not say what to run is a dead end.
|
||||
BOOTSTRAP = "python scripts/bootstrap.py"
|
||||
|
||||
|
||||
def guard_ok(tolk):
|
||||
"""True when ``tolk`` can import the ingestion guard. Runs it; does not
|
||||
look for a file, because what matters is that interpreter's own path."""
|
||||
return 0 == subprocess.call(
|
||||
[tolk, "-c", "import " + GUARD_MODUL],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
|
||||
|
||||
def version_of(tolk):
|
||||
"""The version ``tolk`` reports, or "ukjent" when it will not say."""
|
||||
try:
|
||||
|
|
@ -206,9 +245,11 @@ def resolve_interpreter(env, plugin_root, which=None, gate=None):
|
|||
return None
|
||||
|
||||
|
||||
def main(argv, env=None):
|
||||
def main(argv, env=None, guard=None):
|
||||
if env is None:
|
||||
env = os.environ
|
||||
if guard is None:
|
||||
guard = guard_ok
|
||||
plugin_root = env.get("CLAUDE_PLUGIN_ROOT") or os.path.dirname(SCRIPT_DIR)
|
||||
server = os.path.join(plugin_root, "scripts", "jobbsok_tools.py")
|
||||
|
||||
|
|
@ -243,6 +284,23 @@ def main(argv, env=None):
|
|||
sys.stderr.write("jobbsok-tools: server not found at %s\n" % server)
|
||||
return 1
|
||||
|
||||
# Gate two. Last, because it is the expensive one and there is no point
|
||||
# probing an interpreter that already failed the floor.
|
||||
if not guard(tolk):
|
||||
sys.stderr.write(
|
||||
"jobbsok-tools: %s cannot import %s.\n" % (tolk, GUARD_MODUL)
|
||||
)
|
||||
sys.stderr.write(
|
||||
"jobbsok-tools: run '%s' against the installed plugin; the guard "
|
||||
"is installed with it.\n" % BOOTSTRAP
|
||||
)
|
||||
sys.stderr.write(
|
||||
"jobbsok-tools: refusing to start rather than serving tools that "
|
||||
"write without the ingestion guard. Every skill still works by "
|
||||
"manual paste.\n"
|
||||
)
|
||||
return 1
|
||||
|
||||
# POSIX replaces this process, as the shell version's `exec` did: the MCP
|
||||
# client's child stays the process it spawned, and killing it kills the
|
||||
# server. Windows has no such replacement -- os.execv there starts a new
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue