@tryinget/pi-vault-client
v0.1.0
Published
pi extension package for vault workflows in monorepo runtime
Maintainers
Readme
summary: "Overview and quickstart for monorepo package pi-vault-client." read_when:
- "Starting work in this package workspace." system4d: container: "Monorepo package scaffold for pi vault delivery." compass: "Ship safe package-level iterations inside the shared pi-extensions workspace." engine: "Read package context -> implement focused slice -> validate package + monorepo contracts." fog: "Main drift risk is carrying standalone-repo assumptions into the monorepo package home."
pi-vault-client
Monorepo package for vault workflows in pi.
- Workspace path:
packages/pi-vault-client - Canonical monorepo root:
~/ai-society/softwareco/owned/pi-extensions - Legacy standalone repo: retired from active development
Runtime dependencies
This package expects Prompt Vault schema v9 and pi host runtime APIs.
Prompt rows are consumed through these canonical fields:
artifact_kindcontrol_modeformalization_levelowner_companyvisibility_companiescontrolled_vocabularyexport_to_pi
This package declares pi APIs as peerDependencies:
@mariozechner/pi-coding-agent@mariozechner/pi-ai@mariozechner/pi-tui
The package keeps a narrow local seam over the shared interaction runtime packages (@tryinget/pi-interaction-kit and @tryinget/pi-trigger-adapter) without hand-maintaining a fork of their source.
Current package-boundary contract:
- local monorepo development consumes the shared interaction packages through
file:dependencies pinned to sibling package paths - publish/pack flows rewrite those
file:specs back to versioned manifest entries duringprepackand restore the working manifest inpostpack - no local vendored bridge or bundled-dependency staging remains in the active packaging path
npm run build:runtimegenerates installable.jsentrypoints for this package's TypeScript runtime surface
Runtime .js entrypoints are generated from the package *.ts sources by npm run build:runtime and by prepack, so installed tarballs load through extensions/vault.js instead of relying on TypeScript execution inside node_modules.
When using UI APIs (ctx.ui), guard interactive-only behavior with ctx.hasUI so pi -p non-interactive runs stay stable.
/vault-check is interactive-only; use vault_schema_diagnostics or the isolated headless smoke below for pi -p verification.
Package checks
Run from package directory:
npm install
npm run checkNotes:
npm run checkregenerates the installed-package runtime.jsartifacts before running the package gate.npm run test:compat:live-trigger-contractis the focused validation lane for live/vault:behavior across the shared trigger broker, the150msdebounce contract, and picker fallback behavior.npm run release:checkproves publish-file determinism, static runtime import coverage, clean-room tarball install with locally packed sibling tarballs when required, and headless installed-package smoke through an isolated npm install plus Pi-settings registration check.- if you want the root-owned Pi host compatibility canary for this same seam, run
npm run compat:canary -- --profile current --scenario vault-live-trigger-contractfrom the monorepo root. - if you want to refresh the live-installable runtime without a full check, run
npm run build:runtime.
Or from monorepo root:
cd ~/ai-society/softwareco/owned/pi-extensions
./scripts/ci/full.shRelease metadata
This package writes component metadata in package.json under x-pi-template:
scaffoldModeworkspacePathreleaseComponentreleaseConfigMode
Use these values when wiring monorepo-level release-please component maps.
Public prompt-plane seam
pi-vault-client now exposes a supported package-owned non-UI prompt-plane seam for downstream consumers:
import { createVaultPromptPlaneRuntime } from "@tryinget/pi-vault-client/prompt-plane";Current V3 seam scope:
- prepare a visible template/query/context through package-owned visibility + render rules
- reject caller-supplied
currentCompanywhen it conflicts with resolved env/cwd company context - prepare a continuation from a machine-readable
VaultContinuationEnvelopeV1 - keep continuation operational only through the continuation envelope, not prose parsing
- preserve package-owned prompt preparation semantics without moving runtime ownership into AK
- treat continuation provenance as forward-compatible metadata only; V3 does not yet bind it into receipt/replay lineage
- fail closed when
inherit_current_company: false; cross-company continuation semantics are not part of V3 - reject
exact_templatecontinuations that attemptallow_picker_fallback=true; exact resolution must stay exact in V3 - keep V4 continuation-graph persistence explicitly out of scope for this slice
Use this seam when a downstream package needs deterministic prompt-plane preparation without slash-command or live-trigger wiring.
pi-vault-client also exposes a public dispatch-runtime seam for downstream orchestrators:
import { createVaultDispatchRuntime } from "@tryinget/pi-vault-client/dispatch-runtime";Current dispatch-runtime scope:
- exact active visible template metadata lookup without requiring
export_to_pi=true - dispatch posture classification through the package-owned binding registry
- known loop bindings for
transcendent-iterationandooda - fail-closed posture for loop/workflow templates without execution binding
Do not treat private src/* files as the supported integration API.
Command surface
Kept commands:
/vault- live
/vault: /vault-search/route/vault-stats/vault-check/vault-live-telemetry/vault-dolt-telemetry/vault-fzf-spike/vault-last-receipt— latest local trusted receipt visible to the current company/vault-receipt <execution_id>— exact local trusted receipt if visible to the current company/vault-replay <execution_id>— deterministic replay report for one visible trusted local receipt
Current /vault behavior:
- interactive
/vaultopens the full picker - headless
/vaultand bare headless/vault:now fail closed and require an exact name or fuzzy query instead of auto-selecting the first visible template /vault <exact-name>loads the exact exported-and-visible match directly/vault <fuzzy-query>falls back to picker mode with the query applied- live
/vault:uses the shared interaction runtime, applies a short debounce (150ms) to avoid rapid-fire picker churn, and allows bare/vault:with a follow-up filter prompt in interactive mode - visibility-sensitive slash-command reads (
/vault,/vault:,/vault-search,/route, grounding) now fail closed when no explicit company context is available- set
PI_COMPANYor invoke from a company-scoped cwd - cwd inference now matches exact workspace/company path segments (for example
ai-society/softwareco/...) instead of arbitrary substrings; if your checkout path is ambiguous, setPI_COMPANY
- set
- canonical Pi-visible reads now centralize on
status='active'+export_to_pi=true+ visibility-company filtering /vault, live/vault:,/route, and grounding now queue execution provenance at preparation time but write the actual execution row only when the prepared prompt is sent as a real user message- opening a template in the editor no longer counts as a successful execution by itself
Tool-query defaults:
vault_querydefaults tolimit: 20vault_executionsdefaults tolimit: 20include_contentdefaults tofalseinclude_governancedefaults tofalsevault_query,vault_retrieve,vault_replay, andvault_executionsuse explicit tool-callctx.cwdwhen available so visibility-sensitive reads stay session-aware on the tool surface too- visibility-sensitive tool reads now fail closed when no explicit company context is available on the tool surface
- set
PI_COMPANYor invoke from a company-scoped cwd
- set
- governed ontology/visibility contracts now refresh in-process when the underlying contract files change
- cross-company
visibility_companyoverrides are rejected on the tool surface; use explicit company context for the target company instead of read-side impersonation - optional
intent_textcan re-rank the governed candidate set without changing visibility/status filtering - if you already know your working stage, query directly by
formalization_levelinstead of using semantic rankingvault_query({ formalization_level: ["napkin"] })vault_query({ artifact_kind: ["procedure"], formalization_level: ["workflow"] })
- rotate your query style based on what you know already
- by stage:
vault_query({ formalization_level: ["bounded"] }) - by control mode:
vault_query({ control_mode: ["router"], formalization_level: ["structured"] }) - by artifact kind:
vault_query({ artifact_kind: ["session"] }) - by intent only:
vault_query({ intent_text: "simplify and make retrieval feel almost alien" })
- by stage:
- for exact feedback binding, inspect recent execution provenance first
vault_executions({ template_name: "nexus", limit: 10 })- if Prompt Vault execution-row lookup fails but local receipts still exist,
vault_executionsnow emits an explicit warning and marks the result as partial instead of silently presenting receipt-only success as full truth
- local execution receipts now preserve immutable execution-bound template/company/render snapshots in package-owned JSONL
- default spool path:
~/.pi/agent/state/pi-vault-client/vault-execution-receipts.jsonl - receipt-auth key path:
~/.pi/agent/state/pi-vault-client/vault-execution-receipts.key - emergency fallback spool path:
os.tmpdir()/pi-vault-client/vault-execution-receipts.fallback.jsonl - override directory with
PI_VAULT_RECEIPTS_DIR - manager-written receipts are signed locally (
hmac-sha256) so public receipt/replay/execution surfaces can distinguish trusted package receipts from unsigned/edited legacy JSONL lines - receipt auth keys are provisioned lazily and enforced to local-only permissions (
0600) instead of blocking extension startup when receipt state is unavailable - queued prepared prompts now carry an opaque hidden execution marker so send-time binding can verify the exact prepared prompt at send time
- execution markers are stripped from user messages before the LLM sees them
- if the final sent prompt no longer matches the prepared prompt exactly, Vault skips execution logging and local receipt persistence instead of attributing the edited send to the original template
- if the primary receipt sink is unavailable, Vault falls back to an emergency temp-backed receipt sink before surfacing a send-time warning
- if every receipt sink fails after execution logging succeeds, Vault now surfaces that as an explicit degraded send-time state instead of silently pretending receipt persistence succeeded
vault_executionsprefers local trusted receipts when present so later archive/export drift does not erase recent provenance from this package's own execution pathsvault_replay({ execution_id })and/vault-replay <execution_id>now expose the local replay core directly with deterministicmatch/drift/unavailablereporting keyed to the exact execution id
- default spool path:
vault_dispatch_check({ template_names })classifies exact active visible templates into dispatch postures before execution:text_okorchestrator_loop_requiredorchestrator_workflow_gate_requiredmissing_execution_binding_fail_closed- known loop bindings:
transcendent-iteration -> loop_execute(loop="transcendent"),ooda -> loop_execute(loop="ooda") - workflow-grade templates without explicit bindings are process gates, not inert text: stop, use the owning package surface when one exists, or design the missing execution binding before continuing.
Receipt and replay operator workflow
- receipts are execution-bound, not editor-bound
- prepare a prompt first, then send that prepared prompt as a real user message before expecting a local receipt or replayable
execution_id - if you materially edit the prepared prompt before send, Vault now skips execution logging/receipt persistence rather than recording a misleading template execution
- prepare a prompt first, then send that prepared prompt as a real user message before expecting a local receipt or replayable
- use exact ids end to end
- interactive:
/vault-last-receiptto grab the latest visible receipt, then/vault-receipt <execution_id>or/vault-replay <execution_id> - headless/tooling:
vault_executions({ template_name, limit })to enumerate exact ids, thenvault_replay({ execution_id })
- interactive:
- replay status contract stays fixed
match= regenerated prompt still matches the stored prepared baselinedrift= replay succeeded but the current template/runtime state no longer matches the stored baselineunavailable= replay could not be completed truthfully
- visibility stays fail-closed
- explicit company context is required for receipt inspection and replay surfaces
/vault-receipt <execution_id>and/vault-replay <execution_id>only open visible trusted local receipts in the current company context- replay eligibility now follows the receipt visibility snapshot rather than only the original execution company, so cross-company-visible receipts remain replayable from other visible companies
vault_replay({ execution_id })returns the same replay contract on the tool surface, and treats non-visible receipts asreceipt-missingrather than leaking template identity
Tool mutation surface:
- mutation tools now pass explicit tool-call context when available and disable ambient process-cwd fallback on the tool surface
- if a tool runtime cannot provide
ctx.cwd, prefer settingPI_COMPANYexplicitly for mutation calls
- if a tool runtime cannot provide
vault_insert(...)now inserts new templates only and fails closed when the exactnamealready exists.- mutation requires an explicit active company context (
PI_COMPANYor a company-scoped cwd) owner_companymust match the active mutation company
- mutation requires an explicit active company context (
vault_update({ name, ...patch })is the explicit in-place update path for agents.- exact
nameonly - owner-only: the active mutation company must own the current row
- loads the current row first
- merges only provided fields
- revalidates the merged template against schema-v9 ontology/governance/controlled-vocabulary contracts
- rejects blank content, frontmatter-only bodies, and unsupported explicit
render_enginevalues at mutation time - uses optimistic locking on
version; stale writers fail closed and must retry from fresh state - no fuzzy targeting, bulk mutation, rename behavior, or owner reassignment in this first slice
- exact
vault_rate({ execution_id, ... })now binds feedback to an exact execution row instead of a template name.- use
vault_executions(...)first to retrieve the exactexecution_id - feedback insert succeeds only when exactly one feedback row is written for that execution
- when a trusted local receipt exists for that execution,
vault_rateuses it only as an execution-identity cross-check; current template status and visibility must still pass in Prompt Vault before feedback is written - receipt trust is runtime-issued and internal to this package; callers cannot grant feedback authorization by passing a boolean flag or edited JSON alone
- unsigned/edited legacy receipt JSONL is ignored by operator/tool receipt, replay, and execution-list surfaces, and never authorizes mutation-sensitive feedback visibility
- mutation still uses explicit company context so feedback writes do not silently inherit ambient process cwd
- use
Use /vault-check to inspect schema compatibility, resolved company context, and visibility of key shared templates in the interactive TUI.
Use vault_schema_diagnostics() on the tool surface when headless or when startup is running in schema-mismatch diagnostic mode.
Schema compatibility now requires Prompt Vault schema 9, prompt_templates.version, and the execution/feedback provenance + capture columns (executions.entity_version, executions.output_capture_mode, executions.output_text, feedback.execution_id, etc.) because optimistic locking, exact feedback binding, and execution-capture awareness depend on them.
/vault-check now reports expected vs actual schema version plus missing prompt/execution/feedback columns when the boundary is broken.
When schema compatibility fails, the extension stays loaded in diagnostic mode so /vault-check and vault_schema_diagnostics() remain available even while vault query/mutation surfaces stay gated.
Dolt temp-dir contract
Vault Dolt subprocesses resolve a writable temp directory in this order:
PI_VAULT_TMPDIR${VAULT_DIR}/.dolt/tmp${VAULT_DIR}/.tmpos.tmpdir()
Notes:
- execution probes actual writability by creating and removing a temp directory before Dolt runs, so inode exhaustion and bad paths fail fast
- Vault Dolt child processes now also synthesize a temp-scoped
HOME/.dolt/config_global.jsonoverlay withmetrics.disabled=truesodolt send-metricsdoes not leak UUID temp files into/tmp - that synthetic Dolt home preserves existing host-global string config such as
user.nameanduser.email, plus local version-check marker files when present - diagnostic surfaces (
/vault-check,vault_schema_diagnostics()) inspect the same candidate order without creating repo-local fallback directories - if an explicit
PI_VAULT_TMPDIRis invalid, Vault falls back to the next viable candidate instead of failing closed immediately /vault-checkandvault_schema_diagnostics()now report the resolved Dolt temp status/source/path plus probe attempts- Vault also keeps session-local Dolt execution telemetry for repo-owned observability instead of relying on upstream Dolt telemetry
- interactive:
/vault-dolt-telemetry - headless/tool:
vault_dolt_telemetry({ limit: 15 }) - current summary fields align with the orchestrator boundary telemetry contract where applicable:
total_calls,success_count,failure_count,retained_events,average_latency_ms,max_latency_ms,command_mix, andlatest_failure - vault keeps the additional Dolt-specific
temp_source_mixfield
- interactive:
- recoverable query/exec failures stay quiet by default so fail-closed tests and diagnostic callers do not flood stderr
- set
PI_VAULT_LOG_ERRORS=1when you explicitly want raw Vault boundary diagnostics emitted to stderr
- set
- if a Vault error mentions
Dolt temp dir: ..., inspect both bytes and inodes on host temp storagedf -h /tmpdf -i /tmp
Isolated live validation
For a headless schema-diagnostic call that remains available even during schema mismatch:
PI_COMPANY=software \
pi --no-extensions -e /home/tryinget/ai-society/softwareco/owned/pi-extensions/packages/pi-vault-client -p \
"Do not use bash or read. Call the custom tool named vault_schema_diagnostics exactly once with empty arguments, then reply with only SUCCESS or FAILURE based on whether the tool call succeeded."For a headless query smoke that avoids unrelated auto-discovered extensions:
PI_COMPANY=software \
pi --no-extensions -e /home/tryinget/ai-society/softwareco/owned/pi-extensions/packages/pi-vault-client -p \
"Do not use bash or read. Call the custom tool named vault_query with limit 1 and include_content false, then reply with only SUCCESS or FAILURE based on whether the tool call succeeded."For a headless replay-boundary smoke keyed to an exact execution_id:
PI_COMPANY=software \
pi --no-extensions -e /home/tryinget/ai-society/softwareco/owned/pi-extensions/packages/pi-vault-client -p \
"Do not use bash or read. Call the custom tool named vault_replay exactly once with execution_id 999999. If the tool call succeeds and returns text mentioning both 'status: unavailable' and 'receipt-missing', reply with only SUCCESS. Otherwise reply with only FAILURE."For the focused shared-runtime live-trigger contract (shared broker, 150ms debounce, bare /vault: query prompt, picker fallback):
npm run test:compat:live-trigger-contractFor the root-owned Pi host compatibility canary scenario covering the same seam:
cd /home/tryinget/ai-society/softwareco/owned/pi-extensions
npm run compat:canary -- --profile current --scenario vault-live-trigger-contractFor interactive slash-command validation in an isolated runtime:
export PI_COMPANY=software
pi --no-extensions -e /home/tryinget/ai-society/softwareco/owned/pi-extensions/packages/pi-vault-client
# then inside pi:
# /vault-check
# /vault meta-orchestration
# /vault:meta-orchestrationRender engine contract
Template rendering is a client-layer concern above Prompt Vault storage.
Supported render engines:
none— plain prompt body, no variable substitutionpi-vars— explicit pi-style positional substitution ($1,$2,$@,$ARGUMENTS,${@:N})nunjucks— opt-in safe variable-only interpolation against the governed render context
Phase-1 contract:
- storage remains schema-v9 compatible; render metadata is carried in prompt-content frontmatter
- if
render_engineis omitted, generic execution paths treat the template asnone - generic
/vaultand live/vault:do not auto-detect legacy pi-vars syntax from raw prompt text - specific internal grounding paths may opt into legacy pi-vars auto-detection explicitly while stored templates are migrated
nunjucksrenders only when explicitly declared via frontmatternunjuckssupports variable interpolation such as{{ current_company }},{{ context }}, and{{ args[0] }}only- Nunjucks blocks/comments/filters/function calls/prototype traversal are rejected explicitly
- retrieval stays raw; execution paths strip frontmatter and render on use
- frontmatter parsing accepts both LF and CRLF-authored templates
- literal
{{ ... }}sequences inside substituted data are preserved rather than treated as template syntax
Frontmatter example:
---
render_engine: nunjucks
---
Company: {{ current_company }}
Context: {{ context }}
Template: {{ template_name }}Governed render context keys (path-dependent availability):
argsargumentsarg1,arg2, ...current_companycontexttemplate_name
Current execution behavior:
- grounding flows such as
next-10-expert-suggestionscan explicitly opt into legacy pi-vars auto-detection and pass positional args /vault, live/vault:,/route, and grounding now route through a shared structured preparation step with explicit inputs (currentCompany,context,args,templateName) and structured success/error output/vaultand live/vault:strip frontmatter before inserting prompt text/vaultand live/vault:currently populatecurrent_company,context, andtemplate_namebut do not supply positional args- explicit
pi-varstemplates now fail clearly on execution paths that do not provide the positional args they require; they no longer degrade into silent empty-string substitution - if a Nunjucks template does not reference
context, the shared preparation step appends a deterministic## CONTEXTsection instead of silently dropping caller context - extra render
datacannot override governed keys such ascurrent_company,context,template_name,arguments, orargN - explicit Nunjucks templates render inline at execution time through the safe variable-only subset
- shared preparation now also governs framework-grounding appendices, so migrated framework templates render or fail through the same contract instead of bypassing it as raw text
- unsafe or malformed Nunjucks syntax surfaces explicitly on live vault execution paths
- session-sensitive company resolution is pinned through explicit
ctx.cwdhandoff and session tracking instead of relying only on ambient process cwd - for visibility-sensitive live verification, pin
PI_COMPANYinstead of relying on cwd inference alone
See live render-engine validation for installed-package verification evidence, and legacy render-engine rollout for the operator migration boundary.
Live package activation
Install the package into Pi from its local package path:
npm run build:runtime
pi install /home/tryinget/ai-society/softwareco/owned/pi-extensions/packages/pi-vault-clientThen in Pi:
- run
/reload - verify with a real command or tool call from this package
For publish-safe validation from the package root, run:
npm run release:checkThat release gate now covers:
npm pack --dry-run --json- portable doc-surface validation for shared markdown in the working tree
- packed-artifact markdown/link validation against the actual tarball contents
- packed README immutability audit so published docs links do not float on
main - static runtime dependency audit for bare imports
- packed-manifest dependency rewrite validation
- clean-room tarball install with locally packed sibling tarballs when required
- isolated installed-package dependency-set install in a temporary npm prefix
- Pi-settings registration check for the exact target
PACKAGE_SPEC - installed-package extension registration smoke
Docs discovery
npm run docs:list
npm run docs:list:workspace
npm run docs:list:jsonCopier lifecycle policy
- Keep
.copier-answers.ymlcommitted. - Do not edit
.copier-answers.ymlmanually. - Run update/recopy from a clean destination repo (commit or stash pending changes first).
- Use
copier update --trustwhen.copier-answers.ymlincludes_commitand update is supported. - In non-interactive shells/CI, append
--defaultsto update/recopy. - Use
copier recopy --trustwhen update is unavailable or cannot reconcile cleanly. - After recopy, re-apply local deltas intentionally and run
npm run check.
Docs map
Repository docs for this package live in the monorepo and are linked below through stable GitHub URLs so the published package README stays portable too.
During prepack, those GitHub blob links are pinned to the exact source commit used to build the artifact so the published README does not drift with later main changes.
- Organization operating model
- Project foundation
- Project vision
- Project incentives
- Project resources
- Trusted publishing runbook
- Vault execution receipts architecture
- V4 runtime-receipts runtime-target binding
- Prompt Vault v9 cutover
- Historical Prompt Vault relocation handoff
- Live render-engine validation
- Legacy render-engine rollout
- Company-context hardening diary
- Replay core diary
- Replay surface diary
- Replay docs/tests diary
- Previous receipt hardening diary
- V4 runtime-receipts binding diary
- Next session prompt
