You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(runner): package prompt-template precedence and full resource counting (#189)
The closing pass of issue #189: OQ-019 deferral (b), the package-prompts
hole. Package prompt templates loaded with no precedence enforcement at
all: pi merges package prompt paths first and dedupePrompts is first-wins,
so a staged package's /review silently replaced the repo's own template --
the same inversion skillsOverride closes for skills, live for the one
resource kind that decides what a /name dispatches. That matters doubly
since run.command: the getCommand() pre-check forecloses an UNREGISTERED
/name reaching a same-named template, but a package template shadowing a
protected one was invisible to it. Both halves of what /name runs are now
pinned to reviewed content.
The overlay's prompts/ gains its runtime channel (templates were the one
resource kind with none), merged after discovery so the repo's .pi/prompts
still wins first-path-wins. Repo-beats-package is enforced through the
loader's declared promptsOverride seam; the protected set is PRE-LOADED by
a second, minimal DefaultResourceLoader over the repo then the overlay
prompts dirs, because no per-dir prompt loader is exported at the pin and
the exports map is closed -- pi's own reader through its public surface,
never a hand-rolled parser, built only when packages are staged so the
common job pays nothing.
Counting: packages_loaded grows per-root prompts and themes (the two DATA
kinds a manifest contributes, loaded with no per-root visibility), and a
new post-session commands_registered line reports what each package's
factories actually registered, names and roots only -- a command exists
only once the ExtensionRunner has run, which the loader cannot see. Themes
stay count-only: a theme cannot start work in a headless container, so
precedence enforcement there would be machinery without a failure mode.
Specs: INT-SDK-SESSION-OPTIONS AMENDED, REQ-GLOBAL-PI-OVERLAY AMENDED,
DES-COMMAND-ENTRY-POINT AMENDED (the template half of the fall-through
closure), OQ-019 AMENDED (deferral (b) partially closed, the enablement
mirror half stands on OQ-018). UNCHANGED, checked: INT-CONTAINER-JOB-INPUTS,
INT-PI-PACKAGES-FILE-CONTRACT, REQ-PER-TRIGGER-SKILLS,
REQ-DEPLOYMENT-BOOTSTRAP, DES-OPERATOR-GLOBAL-OVERLAY,
DES-FLOW-RESOLUTION-TWO-ADVISORY-LAYERS, OQ-018, OQ-022.
Signed-off-by: Rob Boerman <robboerman@live.nl>
Copy file name to clipboardExpand all lines: docs/global-pi-overlay.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -73,6 +73,13 @@ refines but never removes the one above:
73
73
|`extensions/` — by default; skip with `--no-extensions`, each one printed by name | the admin extension (hard-blocked) |
74
74
|`packages/<dir>/` — only with `--with-packages`: what `pi-packages.json` declares **plus what you installed with `pi install`**, exact-pinned either way, staged from npm on **your host**| any package whose name looks like the dispatch admin (hard-blocked); a package a repo declares (never installed, see [`SECURITY.md`](../SECURITY.md)) |
75
75
76
+
`prompts/` sits in the never-copied column for `import-pi`, but the RUNTIME channel exists (issue #189):
77
+
a `prompts/` directory you place in the overlay by hand loads in every job as prompt templates, with the
78
+
serviced repo's own `.pi/prompts` winning a name collision -- the same repo-beats-overlay rule skills
79
+
follow, and it is enforced against staged packages too, so what a `/name` template means stays reviewed
80
+
content. `import-pi` still refuses to copy your host prompts for you: OQ-019 records why the enablement
81
+
mirror stops at extensions.
82
+
76
83
The overlay is mounted **read-only** into a container that runs adversarial input, so it must hold **no
77
84
secret**. `import-pi` refuses a `models.json` with a literal `apiKey`, and equally with a literal value
78
85
under an auth-ish provider **header** (a header name carrying `auth`, `api-key`, `token`, `secret` or
Copy file name to clipboardExpand all lines: docs/workflows.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -209,6 +209,8 @@ skills, prompts and themes** at once.
209
209
|---|---|---|
210
210
|**extension order**| staged package extensions load **last**, after the repo's and the overlay's | first-path-wins, so nothing a package ships can shadow something you wrote |
211
211
|**skill collisions**| the **repo's** skill wins a name collision against a package's | pi puts package skill paths first, so precedence is re-imposed after the load rather than merely asserted |
212
+
|**prompt collisions**| the repo's `.pi/prompts` template wins against a package's, and the overlay's `prompts/` now loads at all | same inversion, same fix: what a `/name` template means stays reviewed content, which also matters because `run.command` dispatches by `/name`|
213
+
|**counting**| the `packages_loaded` log line reports extensions, skills, prompts and themes per package, and `commands_registered` reports what each package actually registered | a package that contributed nothing is otherwise indistinguishable from one that worked |
212
214
|**the recursion guard**| any extension named like the admin console, or registering a `dispatch_*` tool, is **dropped** and logged | a staged package must not be able to hand the agent the deployment's own control surface |
213
215
|**the overlay is `:ro`**| a package that writes beside itself fails | the overlay is deploy-time config mounted into an adversarial-input container |
214
216
|**secrets**| the overlay must hold none; `doctor` fails if it does |`:ro` is not confidentiality, and job input is untrusted |
0 commit comments