Packs¶
The pack format primitives. For the conceptual model and the authoring workflow see the Authoring packs guide.
The shipped reference pack is Diligence.
Pack declaration¶
A frozen bundle of pack contents.
Equality and hashing are by (name, version) — NOT by deep field comparison. Behaviors and tools are dataclasses (not hashable); full structural equality would not work and isn't what users care about. The identity that matters is "is this the same pack name and version" — that's what idempotent loading hinges on.
prompt_manifest()
¶
The pack.loaded payload's prompts block. Maps prompt
name to {"version", "hash"}. CONTRACT v0.9 #10.
A typed object the pack contributes.
schema is a Pydantic BaseModel subclass. When the pack is
loaded, graph.add_object(name, data=...) validates against it.
Validation applies only to objects created AFTER the pack loads
(CONTRACT v0.9 #5).
A typed relation the pack contributes.
source_types and target_types are tuples of object type names;
empty means "any".
A policy declared by a pack.
requires_approval: tuple of object type names whose add_object
is gated until runtime.approve(...) is called.
A versioned, content-hashed prompt.
version is the declared human-readable version (for changelogs
and operator messages). content_hash is the SHA-256 of the body
truncated to 16 hex chars; this is the replay contract (the
hash, not the version — see CONTRACT v0.9 #10).
Bases: BaseModel
For packs with no configurable settings. The default
settings_schema.
A Pydantic model with zero fields, so no-settings packs flow
through the same typed-injection machinery as configurable ones
(CONTRACT v0.9 #7) — behaviors can still ask for settings and
get a real instance rather than a None special case.
Discovery¶
Enumerate installed packs via the activegraph.packs entry
point group. Cached per process; call clear_discovery_cache()
to force a re-scan.
Find a discovered pack by name.
Resolves against the discover() scan of installed
entry-point packs and returns the :class:Pack object — pass it
to runtime.load_pack to actually load it. Raises
PackNotFoundError (a LookupError) naming the installed
packs when the name doesn't resolve.
Reset the cached entry-point scan.
discover() memoizes its result for the life of the process
(installed packages don't change under a normal run). Tests that
install or mock packages dynamically call this between cases;
normal usage never needs it.
Scan a directory of *.md prompt files with TOML frontmatter.
Each file MUST start with:
---
version = "1.0.0"
name = "optional_name" # defaults to filename without .md
---
<body>
Returns a tuple of PackPrompt sorted by name. Content hash is
computed over the body (everything after the second --- line
and one separating newline), exactly as it will appear at runtime.
Errors
- missing/malformed frontmatter -> PackPromptLoadError
- missing required
versionfield -> PackPromptLoadError - duplicate prompt name -> PackPromptLoadError
- I/O failure -> PackPromptLoadError
A pack discovered via Python entry points but not yet loaded.
What discover() yields per installed distribution that
registers the activegraph.packs entry-point group: the pack's
name / version, the entry-point string it came from, and
the :class:Pack object itself. Discovery imports the pack module
but changes no runtime state — loading is a separate, explicit
runtime.load_pack call.
Approvals + policies¶
Declared write/tool allowlists for a behavior.
behavior names the behavior the lists scope to; the can_*
fields enumerate the object types, relation types, patches, and
tool names it may touch, and requires_approval routes matching
writes through the pending-approval flow. v0 semantics stand:
fields are recorded with the run for audit; the actively enforced
gate today is approval routing (pack policies, CONTRACT v0.9),
with broader enforcement reserved for a hardening pass.