Project-guidance discovery — internal, no extension required.
STACKED context files, pi-style: guidance is collected from THREE layers and all of them ride into the PROJECT-INSTRUCTIONS system block, outermost first:
~/.vis/AGENTS.md (or ~/.vis/CLAUDE.md)AGENTS.md / CLAUDE.md in every ancestor
directory of the workspace root (outermost first)AGENTS.md / CLAUDE.md at the workspace rootAGENTS.md / CLAUDE.md at each ADDED filesystem
root's own directory (folders granted beyond the
primary workspace — no ancestor walk)Per DIRECTORY precedence is strict: AGENTS.md wins; CLAUDE.md is only consulted when AGENTS.md is absent in that directory. Across directories nothing is dropped — nearer files are rendered LATER so they positionally override outer rules on conflict.
Size policy: NO truncation. Every file goes into the system prompt verbatim. Provider prompt caching amortizes the cost across every iter in the session; trimming would risk dropping the very rule the user is testing. The cwd + per-file (path, mtime, length) marker cache below ensures files are re-read at most once per change.
Failure modes (file unreadable, permissions, I/O error) land in the read-warning vec, NOT in the rendered prompt. The model isn't bound by rules it can't see, but the host knows something is broken.
This namespace replaces the foundation-core/environment/agents.clj that used to live in the extension. Project-guidance discovery is core functionality (drives the system prompt + slim ctx digest); the extension layer no longer owns it.
Project-guidance discovery — internal, no extension required.
STACKED context files, pi-style: guidance is collected from THREE
layers and all of them ride into the PROJECT-INSTRUCTIONS system
block, outermost first:
1. user-global `~/.vis/AGENTS.md` (or `~/.vis/CLAUDE.md`)
2. ancestors `AGENTS.md` / `CLAUDE.md` in every ancestor
directory of the workspace root (outermost first)
3. workspace `AGENTS.md` / `CLAUDE.md` at the workspace root
4. added roots `AGENTS.md` / `CLAUDE.md` at each ADDED filesystem
root's own directory (folders granted beyond the
primary workspace — no ancestor walk)
Per DIRECTORY precedence is strict: AGENTS.md wins; CLAUDE.md is
only consulted when AGENTS.md is absent in that directory. Across
directories nothing is dropped — nearer files are rendered LATER so
they positionally override outer rules on conflict.
Size policy: NO truncation. Every file goes into the system prompt
verbatim. Provider prompt caching amortizes the cost across every
iter in the session; trimming would risk dropping the very rule the
user is testing. The cwd + per-file (path, mtime, length) marker
cache below ensures files are re-read at most once per change.
Failure modes (file unreadable, permissions, I/O error) land in the
read-warning vec, NOT in the rendered prompt. The model isn't bound
by rules it can't see, but the host knows something is broken.
This namespace replaces the foundation-core/environment/agents.clj
that used to live in the extension. Project-guidance discovery is
core functionality (drives the system prompt + slim ctx digest); the
extension layer no longer owns it.Pure helpers for the model-facing context snapshot.
The mutable session state lives outside this namespace; these functions advance the turn/iteration cursor and compute utilization metadata.
Pure helpers for the model-facing context snapshot. The mutable session state lives outside this namespace; these functions advance the turn/iteration cursor and compute utilization metadata.
Slim "session_env" digest. Internal, not extension-owned. STRING-KEYED —
crosses the Python boundary as session["env"], so keys AND enum values
(os/shell/kind/primary_language) are strings, never keywords.
Produces a bounded map the model reads each iter:
{"host" {"os" "shell" "clock"} ; cwd lives in session["workspace"]["root"] "project" {"kind" "primary_language"} "extensions" {"active_count" "aliases"}}
Each slice is small (~50 bytes), so the section costs <200 bytes/turn.
Extensions deep-merge their own slices via :ext/ctx-fn returning
{"session_env" {their-key {…}}}; the merge happens in
ctx-loop/render-block! so internal owns the base section, extensions
layer on top.
Heavy environment scans (full byte-counted language tables, polylith
brick listings, multi-repo git status) live in the foundation-core
focused project-shape helpers for explicit deep-dives. The digest never calls
into extensions — host facts come from System/getProperty,
project shape from a single directory peek. AGENTS.md / CLAUDE.md
contents ride in their own system block (internal.prompt), not here.
Slim `"session_env"` digest. Internal, not extension-owned. STRING-KEYED —
crosses the Python boundary as `session["env"]`, so keys AND enum values
(os/shell/kind/primary_language) are strings, never keywords.
Produces a bounded map the model reads each iter:
{"host" {"os" "shell" "clock"} ; cwd lives in session["workspace"]["root"]
"project" {"kind" "primary_language"}
"extensions" {"active_count" "aliases"}}
Each slice is small (~50 bytes), so the section costs <200 bytes/turn.
Extensions deep-merge their own slices via `:ext/ctx-fn` returning
`{"session_env" {their-key {…}}}`; the merge happens in
`ctx-loop/render-block!` so internal owns the base section, extensions
layer on top.
Heavy environment scans (full byte-counted language tables, polylith
brick listings, multi-repo git status) live in the foundation-core
focused project-shape helpers for explicit deep-dives. The digest never calls
into extensions — host facts come from `System/getProperty`,
project shape from a single directory peek. AGENTS.md / CLAUDE.md
contents ride in their own system block (`internal.prompt`), not here.Loop integration layer for context management.
The loop keeps a per-session :ctx-atom for stable model-facing context
and a separate :turn-state-atom for live execution state and counters.
Council publication identity and references live there only during execution;
activation resources and retry input belong to the session runtime registry.
This namespace stamps the cursor, enriches context with env/access/routing,
and renders the standing context block. Live resources (background shells,
managed REPLs) are deliberately NOT part of ctx: a handle or repl_status
answers for them, so nothing about them is reprinted on every request.
Loop integration layer for context management. The loop keeps a per-session `:ctx-atom` for stable model-facing context and a separate `:turn-state-atom` for live execution state and counters. Council publication identity and references live there only during execution; activation resources and retry input belong to the session runtime registry. This namespace stamps the cursor, enriches context with env/access/routing, and renders the standing context block. Live resources (background shells, managed REPLs) are deliberately NOT part of ctx: a handle or `repl_status` answers for them, so nothing about them is reprinted on every request.
Prompt assembly.
Provider messages are explicit blocks in send order: core system rules,
project instructions (AGENTS.md / CLAUDE.md when present), extension
fragments, current user message. Per-iteration user-role context is the
engine snapshot rendered as a Python dict (session) by the loop.
Prompt assembly. Provider messages are explicit blocks in send order: core system rules, project instructions (AGENTS.md / CLAUDE.md when present), extension fragments, current user message. Per-iteration user-role context is the engine snapshot rendered as a Python dict (`session`) by the loop.
File-based prompt templates — pi-style slash-expandable markdown prompts.
A template is a *.md file whose body becomes the user message when
the user types /<name> [args…]. Discovery, project wins over global:
<workspace>/.vis/prompts/*.md (project)~/.vis/prompts/*.md (user-global)Frontmatter is the same minimal --- fenced key: value block the
harness discovery reads: name (defaults to the filename stem) and
description. The body is the template.
Argument handling matches the common harness convention: when the
body contains $ARGUMENTS every occurrence is substituted with the
raw argument string (empty when none given); otherwise non-blank
args are appended after the body on their own paragraph.
Extensions can contribute DYNAMIC templates through
register-provider! — e.g. the harness extension exposes every
discovered skill as /skill:<name>. File templates win on a name
collision; among providers, registration order wins.
Dispatch: the engine consults expand ONLY for slash texts no
registered extension slash claimed (slash/dispatch returned
:reason :unknown), so real slash commands always win — same
precedence pi uses.
File-based prompt templates — pi-style slash-expandable markdown prompts. A template is a `*.md` file whose body becomes the user message when the user types `/<name> [args…]`. Discovery, project wins over global: 1. `<workspace>/.vis/prompts/*.md` (project) 2. `~/.vis/prompts/*.md` (user-global) Frontmatter is the same minimal `---` fenced `key: value` block the harness discovery reads: `name` (defaults to the filename stem) and `description`. The body is the template. Argument handling matches the common harness convention: when the body contains `$ARGUMENTS` every occurrence is substituted with the raw argument string (empty when none given); otherwise non-blank args are appended after the body on their own paragraph. Extensions can contribute DYNAMIC templates through `register-provider!` — e.g. the harness extension exposes every discovered skill as `/skill:<name>`. File templates win on a name collision; among providers, registration order wins. Dispatch: the engine consults `expand` ONLY for slash texts no registered extension slash claimed (`slash/dispatch` returned `:reason :unknown`), so real slash commands always win — same precedence pi uses.
Pure renderer for the standing agent-facing session snapshot.
render-ctx-static projects the session view and serializes it as a Python
literal with pure JVM code. The live sandbox session dict is built from the
same boundary projection, and render-ctx-delta emits executable updates.
Pure renderer for the standing agent-facing `session` snapshot. `render-ctx-static` projects the session view and serializes it as a Python literal with pure JVM code. The live sandbox `session` dict is built from the same boundary projection, and `render-ctx-delta` emits executable updates.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |