@agentproto/agency-v2 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agentproto contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,23 @@
1
+ # @agentproto/agency-v2
2
+
3
+ AIP-21 `AGENCY.md` reference implementation. A workspace-only successor to AIP-8 that drops the eleven hardcoded agency doctypes (service, engagement, agreement, deliverable, invoice, counterparty, procedure, pricing-model, routine, capacity, agency) and delegates all per-doctype schema work to AIP-18 collections — owning only the workspace root manifest, the engagement lifecycle helpers that span collections, scope axes, and cross-AIP composition with strong governance and work bindings.
4
+
5
+ > **Status: 0.1.0-alpha.** Generated by `scripts/scaffold-aip.mjs` — `build()` and `validate()` bodies are TODOs.
6
+
7
+ Spec: <https://agentproto.sh/docs/aip-21>
8
+
9
+ ## Usage
10
+
11
+ ```ts
12
+ import { defineAgencyV2 } from "@agentproto/agency-v2"
13
+
14
+ const x = defineAgencyV2({
15
+ id: "my-agency-v2",
16
+ description: "Short purpose.",
17
+ // ...
18
+ })
19
+ ```
20
+
21
+ ## License
22
+
23
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ import { createDoctype } from '@agentproto/define-doctype';
3
+
4
+ /**
5
+ * @agentproto/agency-v2 v0.1.0-alpha
6
+ * AIP-21 AGENCY.md `defineAgencyV2` reference implementation.
7
+ */
8
+
9
+ var agencyV2FrontmatterSchema = z.object({ "schema": z.literal("agency.workspace/v2").describe("Discriminator for the AIP-21 workspace doctype."), "name": z.string().regex(new RegExp("^[a-z][a-z0-9-]*[a-z0-9]$")).min(2).max(96).describe("Stable kebab-case identifier for the agency or view."), "title": z.string().min(1).max(200).describe("Human-readable agency title."), "description": z.string().min(1).max(2e3).describe("One-paragraph statement of purpose: what this agency does and who it serves."), "version": z.string().regex(new RegExp("^[0-9]+\\.[0-9]+\\.[0-9]+(-[A-Za-z0-9.-]+)?$")).describe("Semantic version of the WORKSPACE shape. Bump on collection / scope / lifecycle / lint / defaults changes. Independent of the agency's content version."), "extends": z.string().regex(new RegExp("^(\\.\\./|\\./)[^\\s]+/AGENCY\\.md$")).min(1).max(512).describe("OPTIONAL \u2014 relative path to a parent AGENCY.md. Presence makes the manifest a VIEW; absence makes it a WORKSPACE ROOT. Recursive composition; maximum chain depth is 8.").optional(), "appliesTo": z.array(z.string().regex(new RegExp("^(ws://(operators|companies|skills)/[a-z][a-z0-9-]*|\\.\\./[^\\s]+)$")).describe("Either a ws:// ref to an AIP-9 operator / AIP-6 company / AIP-3 skill, or a relative path to a consumer workspace folder.")).refine((arr) => arr.every((item, i) => arr.indexOf(item) == i), { message: "All items must be unique!" }).describe("OPTIONAL \u2014 list of consumers this VIEW adapts the agency for. Hosts MUST refuse the view if any binding does not resolve. Not inherited; views declare their own scope.").optional(), "identity": z.object({ "legalEntity": z.string().regex(new RegExp("^ws://companies/[a-z][a-z0-9-]*$")).describe("OPTIONAL \u2014 AIP-6 ref to the company that legally signs agreements and issues invoices. When set, hosts SHOULD resolve this ref to populate legalName and taxId from the AIP-6 record.").optional(), "legalName": z.string().min(1).max(200).describe("OPTIONAL \u2014 display string for the legal entity name. Used when legalEntity is absent or to override the AIP-6 record's legalName.").optional(), "taxId": z.string().min(1).max(64).describe("OPTIONAL \u2014 tax identifier (VAT, EIN, GST, etc.). Hosts MUST treat this string as opaque; format validation belongs to per-jurisdiction tooling.").optional(), "jurisdiction": z.string().regex(new RegExp("^[A-Z]{2}$")).describe("OPTIONAL \u2014 primary jurisdiction the agency operates under, as ISO 3166-1 alpha-2 (e.g. FR, US, GB, DE).").optional(), "defaultCurrency": z.string().regex(new RegExp("^[A-Z]{3}$")).describe("OPTIONAL \u2014 default currency for new invoices, as ISO 4217 (e.g. EUR, USD, GBP). Per-engagement overrides take precedence.").optional() }).strict().describe("Commercial-flavored identity block. All fields optional; agencies operating as a sole operator with no counterparty billing may omit the block entirely.").optional(), "executor": z.string().regex(new RegExp("^ws://operators/[a-z][a-z0-9-]*$")).describe("OPTIONAL \u2014 AIP-9 default executor operator. The host activates this operator when an item with no explicit assignee surfaces.").optional(), "governance": z.string().min(1).max(512).describe("OPTIONAL \u2014 AIP-7 policy or audit binding. May be a path to an AIP-7 policy file or a ws:// ref. Status-transition approvals, signature gates on agreements, and audit log routing flow through this ref. Agreements MUST be signed; the default policy lives here.").optional(), "knowledge": z.string().regex(new RegExp("^ws://wikis/[a-z][a-z0-9-]*(/KNOWLEDGE\\.md)?$")).describe("OPTIONAL \u2014 AIP-10 KNOWLEDGE.md ref. Wiki this agency refers to (case studies, prior-art, methodology).").optional(), "work": z.string().regex(new RegExp("^ws://workspaces/[a-z][a-z0-9-]*(/WORK\\.md)?$")).describe("OPTIONAL \u2014 AIP-20 work workspace binding. Items in `deliverable` MAY be tracked as work items in the bound workspace.").optional(), "playbook": z.string().regex(new RegExp("^ws://playbooks/[a-z][a-z0-9-]*$")).describe("OPTIONAL \u2014 AIP-12 active playbook. Governs the routine plays this agency runs.").optional(), "companies": z.string().regex(new RegExp("^ws://companies(/[a-z][a-z0-9-]*)?$")).describe("OPTIONAL \u2014 AIP-6 companies root. Resolution root for `counterparty` items: a counterparty's companyRef resolves under this binding.").optional(), "collections": z.array(z.any()).describe("Collections enabled by this agency. Three forms supported: inline (full COLLECTION.md frontmatter), file ref, or registry import. Merge-by-effective-name (alias if set, otherwise the collection's name) across the extends chain.").default([]), "lifecycle": z.object({ "enabled": z.boolean().describe("Whether cross-collection lifecycle propagation is active. When false, no lifecycle rules fire \u2014 items keep their stored statuses regardless of related items.").default(false), "rules": z.array(z.object({ "id": z.string().regex(new RegExp("^[a-z][a-z0-9-]*$")).describe("Stable kebab-case rule id. Merge key when composing across extends."), "when": z.string().regex(new RegExp("^(all-items-in-collection-terminal|any-linked-item-status|linked-item-terminal|no-linked-items|custom:[a-z][a-z0-9-]*)$")).describe("Predicate id from the recognised vocabulary. Custom predicates are host-defined keyed by `id`."), "forCollection": z.string().regex(new RegExp("^[a-z][a-z0-9-]*[a-z0-9]$")).describe("Effective name of the collection whose items receive the bubbled status. MUST appear in the workspace's merged collections array."), "bubbleStatus": z.string().regex(new RegExp("^[a-z][a-z0-9-]*$")).describe("Status id to set on the target item when the predicate holds. MUST exist on the forCollection's state machine."), "params": z.record(z.string(), z.any()).describe("Predicate parameters. Common keys: sourceCollection (collection whose items the predicate inspects), linkField (field on source items pointing at the target), terminalStatuses (subset of terminal statuses to count), statusEquals (specific status to match).").default({}) }).strict()).describe("Cross-collection lifecycle rules. Merge-by-id vs parent. Hosts MUST detect graph cycles in the (forCollection, sourceCollection) edge set and refuse with agency_lifecycle_cycle (HARD).").default([]) }).strict().describe("Engagement lifecycle helpers \u2014 workspace-level rules for cross-collection state propagation. The AIP-21 distinctive contribution.").optional(), "scope": z.object({ "containment": z.object({ "enabled": z.boolean().describe("Whether the containment axis is active. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false (would orphan items). Refusal: agency_scope_disable (HARD).").default(true), "field": z.string().regex(new RegExp("^[a-z][a-zA-Z0-9_]*$")).describe("Item field name carrying the containment ref.").default("parent"), "rules": z.object({ "allowedKinds": z.array(z.string().regex(new RegExp("^[a-z][a-z0-9-]*[a-z0-9]$"))).refine((arr) => arr.every((item, i) => arr.indexOf(item) == i), { message: "All items must be unique!" }).describe("OPTIONAL \u2014 collection names allowed as containment parents.").optional(), "maxDepth": z.number().int().gte(1).lte(32).describe("OPTIONAL \u2014 maximum containment depth.").optional() }).strict().describe("OPTIONAL containment constraints.").optional() }).strict().describe("Containment axis (parent/child).").optional(), "applicability": z.object({ "enabled": z.boolean().describe("Whether the applicability axis is active.").default(false), "field": z.string().regex(new RegExp("^[a-z][a-zA-Z0-9_]*$")).describe("Item field name carrying the applicability ref list.").default("appliesTo"), "valueClass": z.string().regex(new RegExp("^[a-z][a-z0-9-]*$")).describe("Class of refs the field accepts. Recognised classes: client, market, service, company, role, role-and-company, operator. ONE-WAY SWITCH: once set at any ancestor, descendants MUST NOT change. Refusal: agency_scope_value_class_drift (HARD).").optional() }).strict().describe("Applicability axis (who the item is about / scoped to).").optional(), "ownership": z.object({ "enabled": z.boolean().describe("Whether the ownership axis is active.").default(true), "field": z.string().regex(new RegExp("^[a-z][a-zA-Z0-9_]*$")).describe("Workspace-level default item field name carrying the ownership ref.").default("owner"), "policy": z.enum(["strict", "inherit", "open"]).describe("Workspace-level ownership policy. 'strict' requires every collection's ownership.required to be true; 'inherit' delegates; 'open' permits any collection to omit ownership.").default("inherit") }).strict().describe("Ownership axis (who is doing the item).").optional() }).strict().describe("Workspace-level scope axes \u2014 three orthogonal axes (containment / applicability / ownership) declared once per agency.").optional(), "lints": z.array(z.object({ "id": z.string().regex(new RegExp("^[a-z][a-z0-9-]*$")).describe("Stable kebab-case lint id. Merge key when composing with extends parent."), "kind": z.enum(["stale-engagement", "unsigned-agreement", "overdue-invoice", "broken-procedure-ref", "orphan-across-collections", "stale-tree", "broken-parent-ref", "scope-mismatch", "custom"]).describe("Workspace-spanning lint algorithm. AIP-18 per-collection lints (missing-owner, overdue, required-field, etc.) live on COLLECTION.md and are NOT redeclared here. 'custom' delegates to a host-defined check identified by `id`."), "severity": z.enum(["error", "warn", "info"]).describe("Lint severity. Children may soften; governance policies MAY forbid softening below `error`."), "params": z.record(z.string(), z.any()).describe("Kind-specific parameters.").default({}) }).strict()).describe("Workspace-spanning lints. Merge-by-id vs parent.").default([]), "defaults": z.object({ "workflow": z.string().min(1).max(512).describe("OPTIONAL \u2014 default AIP-15 WORKFLOW.md path or ref.").optional(), "approvalClass": z.string().regex(new RegExp("^(auto|always|on-mutate|policy:[A-Za-z0-9_./:-]+)$")).describe("Approval class for mutations. 'auto' = no gate; 'always' = every mutation requires approval; 'on-mutate' = approval on field-level mutations; 'policy:<ref>' = delegate to an AIP-7 policy.").optional(), "auditMutations": z.boolean().describe("Whether mutations are audited. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false. Refusal: agency_audit_downgrade (HARD).").default(false) }).strict().describe("Routine workflow defaults. Composes with AIP-15.").optional(), "engagement": z.object({ "terms": z.object({ "contractRequired": z.boolean().describe("Whether engagement items require a corresponding agreement item. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false (commercial protection against engagements without paperwork). Refusal: agency_contract_required_downgrade (HARD).").default(false), "defaultPaymentTerms": z.string().regex(new RegExp("^(net-[0-9]+|due-on-receipt|prepaid|[a-z][a-z0-9-]*)$")).describe("OPTIONAL \u2014 default payment terms for new invoices. Common values: net-15, net-30, net-60, due-on-receipt, prepaid. Custom kebab-case strings permitted.").optional(), "defaultCurrency": z.string().regex(new RegExp("^[A-Z]{3}$")).describe("OPTIONAL \u2014 default currency for engagement-derived invoices, as ISO 4217. Falls back to identity.defaultCurrency if unset.").optional() }).strict().describe("Default commercial terms applied to new engagement and invoice items.").optional() }).strict().describe("Engagement-specific terms (AIP-21 distinctive).").optional(), "display": z.object({ "homePage": z.string().regex(new RegExp("^[A-Za-z0-9][A-Za-z0-9_:-]*$")).describe("OPTIONAL \u2014 id of the item to use as the agency landing page.").optional(), "defaultGrouping": z.enum(["kind", "status", "counterparty", "engagement"]).describe("Default grouping for list views.").optional(), "defaultView": z.enum(["list", "board", "timeline", "dashboard"]).describe("Default rendering mode.").optional() }).strict().describe("Display hints for UIs that render the agency. Runtime-agnostic.").optional(), "metadata": z.record(z.string(), z.any()).describe("Vendor-specific extensions, namespaced under <vendor>. Deep-merged across the extends chain. MUST NOT change the meaning of any spec field.").default({}) }).strict().and(z.any().describe("A view (any manifest with appliesTo set) MUST extend a parent. A workspace-root manifest has neither field.")).describe("Validates the YAML frontmatter portion of an AIP-21 AGENCY.md (workspace root or per-context view). The single doctype 'agency.workspace/v2' is used in both modes; the host distinguishes by checking whether `extends` is set. Per-doctype schemas (service, engagement, agreement, deliverable, invoice, counterparty, procedure, pricing-model, routine, capacity) are delegated to AIP-18 (COLLECTION.md / ITEM.md).");
10
+ var defineAgencyV2 = createDoctype({
11
+ aip: 21,
12
+ name: "agency-v2",
13
+ readIdentity: (def) => def.name,
14
+ validate(def) {
15
+ const d = def;
16
+ if (Array.isArray(d.appliesTo) && d.appliesTo.length > 0 && d.extends == null) {
17
+ throw new Error(
18
+ `defineAgencyV2 (AIP-21): appliesTo is non-empty \u2014 extends MUST be set`
19
+ );
20
+ }
21
+ const result = agencyV2FrontmatterSchema.safeParse(def);
22
+ if (!result.success) {
23
+ throw new Error(
24
+ `defineAgencyV2 (AIP-21): ${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`
25
+ );
26
+ }
27
+ },
28
+ build(def) {
29
+ return { ...def };
30
+ }
31
+ });
32
+
33
+ export { agencyV2FrontmatterSchema, defineAgencyV2 };
34
+ //# sourceMappingURL=chunk-2EJ3V4IK.mjs.map
35
+ //# sourceMappingURL=chunk-2EJ3V4IK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema.ts","../src/define-agency-v2.ts"],"names":[],"mappings":"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","file":"chunk-2EJ3V4IK.mjs","sourcesContent":["/**\n * AIP-21 AGENCY.md frontmatter zod schema.\n *\n * Generated from `resources/aip-21/draft/AGENCY.schema.json` via\n * json-schema-to-zod. Imported by both `define-agency-v2.ts` (TS path\n * validation) and `manifest/index.ts` (.md path validation) so every\n * field-level constraint runs in both authoring paths from a single\n * source of truth — re-run scaffold-aip to refresh after spec changes.\n *\n * Cross-field rules (if/then/allOf in JSON Schema) don't translate\n * cleanly and live in `define-agency-v2.ts`'s `validate(def)` instead.\n */\n\nimport { z } from \"zod\"\n\nexport const agencyV2FrontmatterSchema = z.object({ \"schema\": z.literal(\"agency.workspace/v2\").describe(\"Discriminator for the AIP-21 workspace doctype.\"), \"name\": z.string().regex(new RegExp(\"^[a-z][a-z0-9-]*[a-z0-9]$\")).min(2).max(96).describe(\"Stable kebab-case identifier for the agency or view.\"), \"title\": z.string().min(1).max(200).describe(\"Human-readable agency title.\"), \"description\": z.string().min(1).max(2000).describe(\"One-paragraph statement of purpose: what this agency does and who it serves.\"), \"version\": z.string().regex(new RegExp(\"^[0-9]+\\\\.[0-9]+\\\\.[0-9]+(-[A-Za-z0-9.-]+)?$\")).describe(\"Semantic version of the WORKSPACE shape. Bump on collection / scope / lifecycle / lint / defaults changes. Independent of the agency's content version.\"), \"extends\": z.string().regex(new RegExp(\"^(\\\\.\\\\./|\\\\./)[^\\\\s]+/AGENCY\\\\.md$\")).min(1).max(512).describe(\"OPTIONAL — relative path to a parent AGENCY.md. Presence makes the manifest a VIEW; absence makes it a WORKSPACE ROOT. Recursive composition; maximum chain depth is 8.\").optional(), \"appliesTo\": z.array(z.string().regex(new RegExp(\"^(ws://(operators|companies|skills)/[a-z][a-z0-9-]*|\\\\.\\\\./[^\\\\s]+)$\")).describe(\"Either a ws:// ref to an AIP-9 operator / AIP-6 company / AIP-3 skill, or a relative path to a consumer workspace folder.\")).refine((arr) => arr.every((item, i) => arr.indexOf(item) == i), { message: \"All items must be unique!\" }).describe(\"OPTIONAL — list of consumers this VIEW adapts the agency for. Hosts MUST refuse the view if any binding does not resolve. Not inherited; views declare their own scope.\").optional(), \"identity\": z.object({ \"legalEntity\": z.string().regex(new RegExp(\"^ws://companies/[a-z][a-z0-9-]*$\")).describe(\"OPTIONAL — AIP-6 ref to the company that legally signs agreements and issues invoices. When set, hosts SHOULD resolve this ref to populate legalName and taxId from the AIP-6 record.\").optional(), \"legalName\": z.string().min(1).max(200).describe(\"OPTIONAL — display string for the legal entity name. Used when legalEntity is absent or to override the AIP-6 record's legalName.\").optional(), \"taxId\": z.string().min(1).max(64).describe(\"OPTIONAL — tax identifier (VAT, EIN, GST, etc.). Hosts MUST treat this string as opaque; format validation belongs to per-jurisdiction tooling.\").optional(), \"jurisdiction\": z.string().regex(new RegExp(\"^[A-Z]{2}$\")).describe(\"OPTIONAL — primary jurisdiction the agency operates under, as ISO 3166-1 alpha-2 (e.g. FR, US, GB, DE).\").optional(), \"defaultCurrency\": z.string().regex(new RegExp(\"^[A-Z]{3}$\")).describe(\"OPTIONAL — default currency for new invoices, as ISO 4217 (e.g. EUR, USD, GBP). Per-engagement overrides take precedence.\").optional() }).strict().describe(\"Commercial-flavored identity block. All fields optional; agencies operating as a sole operator with no counterparty billing may omit the block entirely.\").optional(), \"executor\": z.string().regex(new RegExp(\"^ws://operators/[a-z][a-z0-9-]*$\")).describe(\"OPTIONAL — AIP-9 default executor operator. The host activates this operator when an item with no explicit assignee surfaces.\").optional(), \"governance\": z.string().min(1).max(512).describe(\"OPTIONAL — AIP-7 policy or audit binding. May be a path to an AIP-7 policy file or a ws:// ref. Status-transition approvals, signature gates on agreements, and audit log routing flow through this ref. Agreements MUST be signed; the default policy lives here.\").optional(), \"knowledge\": z.string().regex(new RegExp(\"^ws://wikis/[a-z][a-z0-9-]*(/KNOWLEDGE\\\\.md)?$\")).describe(\"OPTIONAL — AIP-10 KNOWLEDGE.md ref. Wiki this agency refers to (case studies, prior-art, methodology).\").optional(), \"work\": z.string().regex(new RegExp(\"^ws://workspaces/[a-z][a-z0-9-]*(/WORK\\\\.md)?$\")).describe(\"OPTIONAL — AIP-20 work workspace binding. Items in `deliverable` MAY be tracked as work items in the bound workspace.\").optional(), \"playbook\": z.string().regex(new RegExp(\"^ws://playbooks/[a-z][a-z0-9-]*$\")).describe(\"OPTIONAL — AIP-12 active playbook. Governs the routine plays this agency runs.\").optional(), \"companies\": z.string().regex(new RegExp(\"^ws://companies(/[a-z][a-z0-9-]*)?$\")).describe(\"OPTIONAL — AIP-6 companies root. Resolution root for `counterparty` items: a counterparty's companyRef resolves under this binding.\").optional(), \"collections\": z.array(z.any()).describe(\"Collections enabled by this agency. Three forms supported: inline (full COLLECTION.md frontmatter), file ref, or registry import. Merge-by-effective-name (alias if set, otherwise the collection's name) across the extends chain.\").default([] as never), \"lifecycle\": z.object({ \"enabled\": z.boolean().describe(\"Whether cross-collection lifecycle propagation is active. When false, no lifecycle rules fire — items keep their stored statuses regardless of related items.\").default(false), \"rules\": z.array(z.object({ \"id\": z.string().regex(new RegExp(\"^[a-z][a-z0-9-]*$\")).describe(\"Stable kebab-case rule id. Merge key when composing across extends.\"), \"when\": z.string().regex(new RegExp(\"^(all-items-in-collection-terminal|any-linked-item-status|linked-item-terminal|no-linked-items|custom:[a-z][a-z0-9-]*)$\")).describe(\"Predicate id from the recognised vocabulary. Custom predicates are host-defined keyed by `id`.\"), \"forCollection\": z.string().regex(new RegExp(\"^[a-z][a-z0-9-]*[a-z0-9]$\")).describe(\"Effective name of the collection whose items receive the bubbled status. MUST appear in the workspace's merged collections array.\"), \"bubbleStatus\": z.string().regex(new RegExp(\"^[a-z][a-z0-9-]*$\")).describe(\"Status id to set on the target item when the predicate holds. MUST exist on the forCollection's state machine.\"), \"params\": z.record(z.string(), z.any()).describe(\"Predicate parameters. Common keys: sourceCollection (collection whose items the predicate inspects), linkField (field on source items pointing at the target), terminalStatuses (subset of terminal statuses to count), statusEquals (specific status to match).\").default({} as never) }).strict()).describe(\"Cross-collection lifecycle rules. Merge-by-id vs parent. Hosts MUST detect graph cycles in the (forCollection, sourceCollection) edge set and refuse with agency_lifecycle_cycle (HARD).\").default([] as never) }).strict().describe(\"Engagement lifecycle helpers — workspace-level rules for cross-collection state propagation. The AIP-21 distinctive contribution.\").optional(), \"scope\": z.object({ \"containment\": z.object({ \"enabled\": z.boolean().describe(\"Whether the containment axis is active. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false (would orphan items). Refusal: agency_scope_disable (HARD).\").default(true), \"field\": z.string().regex(new RegExp(\"^[a-z][a-zA-Z0-9_]*$\")).describe(\"Item field name carrying the containment ref.\").default(\"parent\"), \"rules\": z.object({ \"allowedKinds\": z.array(z.string().regex(new RegExp(\"^[a-z][a-z0-9-]*[a-z0-9]$\"))).refine((arr) => arr.every((item, i) => arr.indexOf(item) == i), { message: \"All items must be unique!\" }).describe(\"OPTIONAL — collection names allowed as containment parents.\").optional(), \"maxDepth\": z.number().int().gte(1).lte(32).describe(\"OPTIONAL — maximum containment depth.\").optional() }).strict().describe(\"OPTIONAL containment constraints.\").optional() }).strict().describe(\"Containment axis (parent/child).\").optional(), \"applicability\": z.object({ \"enabled\": z.boolean().describe(\"Whether the applicability axis is active.\").default(false), \"field\": z.string().regex(new RegExp(\"^[a-z][a-zA-Z0-9_]*$\")).describe(\"Item field name carrying the applicability ref list.\").default(\"appliesTo\"), \"valueClass\": z.string().regex(new RegExp(\"^[a-z][a-z0-9-]*$\")).describe(\"Class of refs the field accepts. Recognised classes: client, market, service, company, role, role-and-company, operator. ONE-WAY SWITCH: once set at any ancestor, descendants MUST NOT change. Refusal: agency_scope_value_class_drift (HARD).\").optional() }).strict().describe(\"Applicability axis (who the item is about / scoped to).\").optional(), \"ownership\": z.object({ \"enabled\": z.boolean().describe(\"Whether the ownership axis is active.\").default(true), \"field\": z.string().regex(new RegExp(\"^[a-z][a-zA-Z0-9_]*$\")).describe(\"Workspace-level default item field name carrying the ownership ref.\").default(\"owner\"), \"policy\": z.enum([\"strict\",\"inherit\",\"open\"]).describe(\"Workspace-level ownership policy. 'strict' requires every collection's ownership.required to be true; 'inherit' delegates; 'open' permits any collection to omit ownership.\").default(\"inherit\") }).strict().describe(\"Ownership axis (who is doing the item).\").optional() }).strict().describe(\"Workspace-level scope axes — three orthogonal axes (containment / applicability / ownership) declared once per agency.\").optional(), \"lints\": z.array(z.object({ \"id\": z.string().regex(new RegExp(\"^[a-z][a-z0-9-]*$\")).describe(\"Stable kebab-case lint id. Merge key when composing with extends parent.\"), \"kind\": z.enum([\"stale-engagement\",\"unsigned-agreement\",\"overdue-invoice\",\"broken-procedure-ref\",\"orphan-across-collections\",\"stale-tree\",\"broken-parent-ref\",\"scope-mismatch\",\"custom\"]).describe(\"Workspace-spanning lint algorithm. AIP-18 per-collection lints (missing-owner, overdue, required-field, etc.) live on COLLECTION.md and are NOT redeclared here. 'custom' delegates to a host-defined check identified by `id`.\"), \"severity\": z.enum([\"error\",\"warn\",\"info\"]).describe(\"Lint severity. Children may soften; governance policies MAY forbid softening below `error`.\"), \"params\": z.record(z.string(), z.any()).describe(\"Kind-specific parameters.\").default({} as never) }).strict()).describe(\"Workspace-spanning lints. Merge-by-id vs parent.\").default([] as never), \"defaults\": z.object({ \"workflow\": z.string().min(1).max(512).describe(\"OPTIONAL — default AIP-15 WORKFLOW.md path or ref.\").optional(), \"approvalClass\": z.string().regex(new RegExp(\"^(auto|always|on-mutate|policy:[A-Za-z0-9_./:-]+)$\")).describe(\"Approval class for mutations. 'auto' = no gate; 'always' = every mutation requires approval; 'on-mutate' = approval on field-level mutations; 'policy:<ref>' = delegate to an AIP-7 policy.\").optional(), \"auditMutations\": z.boolean().describe(\"Whether mutations are audited. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false. Refusal: agency_audit_downgrade (HARD).\").default(false) }).strict().describe(\"Routine workflow defaults. Composes with AIP-15.\").optional(), \"engagement\": z.object({ \"terms\": z.object({ \"contractRequired\": z.boolean().describe(\"Whether engagement items require a corresponding agreement item. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false (commercial protection against engagements without paperwork). Refusal: agency_contract_required_downgrade (HARD).\").default(false), \"defaultPaymentTerms\": z.string().regex(new RegExp(\"^(net-[0-9]+|due-on-receipt|prepaid|[a-z][a-z0-9-]*)$\")).describe(\"OPTIONAL — default payment terms for new invoices. Common values: net-15, net-30, net-60, due-on-receipt, prepaid. Custom kebab-case strings permitted.\").optional(), \"defaultCurrency\": z.string().regex(new RegExp(\"^[A-Z]{3}$\")).describe(\"OPTIONAL — default currency for engagement-derived invoices, as ISO 4217. Falls back to identity.defaultCurrency if unset.\").optional() }).strict().describe(\"Default commercial terms applied to new engagement and invoice items.\").optional() }).strict().describe(\"Engagement-specific terms (AIP-21 distinctive).\").optional(), \"display\": z.object({ \"homePage\": z.string().regex(new RegExp(\"^[A-Za-z0-9][A-Za-z0-9_:-]*$\")).describe(\"OPTIONAL — id of the item to use as the agency landing page.\").optional(), \"defaultGrouping\": z.enum([\"kind\",\"status\",\"counterparty\",\"engagement\"]).describe(\"Default grouping for list views.\").optional(), \"defaultView\": z.enum([\"list\",\"board\",\"timeline\",\"dashboard\"]).describe(\"Default rendering mode.\").optional() }).strict().describe(\"Display hints for UIs that render the agency. Runtime-agnostic.\").optional(), \"metadata\": z.record(z.string(), z.any()).describe(\"Vendor-specific extensions, namespaced under <vendor>. Deep-merged across the extends chain. MUST NOT change the meaning of any spec field.\").default({} as never) }).strict().and(z.any().describe(\"A view (any manifest with appliesTo set) MUST extend a parent. A workspace-root manifest has neither field.\")).describe(\"Validates the YAML frontmatter portion of an AIP-21 AGENCY.md (workspace root or per-context view). The single doctype 'agency.workspace/v2' is used in both modes; the host distinguishes by checking whether `extends` is set. Per-doctype schemas (service, engagement, agreement, deliverable, invoice, counterparty, procedure, pricing-model, routine, capacity) are delegated to AIP-18 (COLLECTION.md / ITEM.md).\")\n\nexport type AgencyV2Frontmatter = z.infer<typeof agencyV2FrontmatterSchema>\n","import { createDoctype } from \"@agentproto/define-doctype\"\nimport { agencyV2FrontmatterSchema } from \"./schema.js\"\nimport type { AgencyV2Definition, AgencyV2Handle } from \"./types.js\"\n\n/**\n * AIP-21 reference implementation of `defineAgencyV2`.\n *\n * Built on `createDoctype` so the cross-AIP invariants (id pattern,\n * description length, top-level freeze, \"defineAgencyV2 (AIP-21): …\"\n * error prefix) run uniformly with every other AIP defineX.\n *\n * Field-level validation runs the schema-derived zod from\n * `./schema.ts` against the input. Same source of truth as the .md\n * path uses (`parseAgencyV2Manifest`), so a malformed TS-authored\n * definition fails with the same diagnostic as a malformed manifest.\n * Cross-field rules go in `validate(def)` after the zod check.\n *\n * Identity / description extractors detected from the JSON Schema:\n * readIdentity: def.name\n * readDescription: def.description.\n */\nexport const defineAgencyV2 = createDoctype<AgencyV2Definition, AgencyV2Handle>({\n aip: 21,\n name: \"agency-v2\",\n readIdentity: (def) => def.name,\n validate(def) {\n // AIP-21 rule (shared with AIP-18/20/22/23/24): appliesTo non-empty\n // ⇒ extends required. Runs before field-level zod so a structural\n // miss surfaces before the cascade of \"missing required field\".\n const d = def as { appliesTo?: readonly unknown[]; extends?: unknown }\n if (\n Array.isArray(d.appliesTo) &&\n d.appliesTo.length > 0 &&\n d.extends == null\n ) {\n throw new Error(\n `defineAgencyV2 (AIP-21): appliesTo is non-empty — extends MUST be set`,\n )\n }\n const result = agencyV2FrontmatterSchema.safeParse(def)\n if (!result.success) {\n throw new Error(\n `defineAgencyV2 (AIP-21): ${result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}`,\n )\n }\n },\n build(def) {\n // Default build: spread the validated definition into a fresh object.\n // Hand-tune for nested freezing (Object.freeze on arrays/objects) and\n // for fields that need defaults applied — see @agentproto/operator\n // for a reference shape.\n return { ...def } as AgencyV2Handle\n },\n})\n"]}
@@ -0,0 +1,37 @@
1
+ import { A as AgencyV2Definition } from './types-DOmT5DLV.js';
2
+ export { a as AgencyV2Handle } from './types-DOmT5DLV.js';
3
+
4
+ /**
5
+ * AIP-21 reference implementation of `defineAgencyV2`.
6
+ *
7
+ * Built on `createDoctype` so the cross-AIP invariants (id pattern,
8
+ * description length, top-level freeze, "defineAgencyV2 (AIP-21): …"
9
+ * error prefix) run uniformly with every other AIP defineX.
10
+ *
11
+ * Field-level validation runs the schema-derived zod from
12
+ * `./schema.ts` against the input. Same source of truth as the .md
13
+ * path uses (`parseAgencyV2Manifest`), so a malformed TS-authored
14
+ * definition fails with the same diagnostic as a malformed manifest.
15
+ * Cross-field rules go in `validate(def)` after the zod check.
16
+ *
17
+ * Identity / description extractors detected from the JSON Schema:
18
+ * readIdentity: def.name
19
+ * readDescription: def.description.
20
+ */
21
+ declare const defineAgencyV2: (def: AgencyV2Definition) => Readonly<AgencyV2Definition>;
22
+
23
+ /**
24
+ * @agentproto/agency-v2 — AIP-21 AGENCY.md `defineAgencyV2` reference impl.
25
+ *
26
+ * A workspace-only successor to AIP-8 that drops the eleven hardcoded agency doctypes (service, engagement, agreement, deliverable, invoice, counterparty, procedure, pricing-model, routine, capacity, agency) and delegates all per-doctype schema work to AIP-18 collections — owning only the workspace root manifest, the engagement lifecycle helpers that span collections, scope axes, and cross-AIP composition with strong governance and work bindings.
27
+ *
28
+ * Spec: https://agentproto.sh/docs/aip-21
29
+ *
30
+ * Authoring paths:
31
+ * - TS: `defineAgencyV2({...})` → `AgencyV2Handle`
32
+ * - MD: `parseAgencyV2Manifest(src) → agencyV2FromManifest({...})` → `AgencyV2Handle`
33
+ */
34
+ declare const SPEC_NAME: "agentagency-v2/v1";
35
+ declare const SPEC_VERSION: "1.0.0-alpha";
36
+
37
+ export { AgencyV2Definition, SPEC_NAME, SPEC_VERSION, defineAgencyV2 };
package/dist/index.mjs ADDED
@@ -0,0 +1,14 @@
1
+ export { defineAgencyV2 } from './chunk-2EJ3V4IK.mjs';
2
+
3
+ /**
4
+ * @agentproto/agency-v2 v0.1.0-alpha
5
+ * AIP-21 AGENCY.md `defineAgencyV2` reference implementation.
6
+ */
7
+
8
+ // src/index.ts
9
+ var SPEC_NAME = "agentagency-v2/v1";
10
+ var SPEC_VERSION = "1.0.0-alpha";
11
+
12
+ export { SPEC_NAME, SPEC_VERSION };
13
+ //# sourceMappingURL=index.mjs.map
14
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;AAYO,IAAM,SAAA,GAAY;AAClB,IAAM,YAAA,GAAe","file":"index.mjs","sourcesContent":["/**\n * @agentproto/agency-v2 — AIP-21 AGENCY.md `defineAgencyV2` reference impl.\n *\n * A workspace-only successor to AIP-8 that drops the eleven hardcoded agency doctypes (service, engagement, agreement, deliverable, invoice, counterparty, procedure, pricing-model, routine, capacity, agency) and delegates all per-doctype schema work to AIP-18 collections — owning only the workspace root manifest, the engagement lifecycle helpers that span collections, scope axes, and cross-AIP composition with strong governance and work bindings.\n *\n * Spec: https://agentproto.sh/docs/aip-21\n *\n * Authoring paths:\n * - TS: `defineAgencyV2({...})` → `AgencyV2Handle`\n * - MD: `parseAgencyV2Manifest(src) → agencyV2FromManifest({...})` → `AgencyV2Handle`\n */\n\nexport const SPEC_NAME = \"agentagency-v2/v1\" as const\nexport const SPEC_VERSION = \"1.0.0-alpha\" as const\n\nexport { defineAgencyV2 } from \"./define-agency-v2.js\"\nexport type { AgencyV2Definition, AgencyV2Handle } from \"./types.js\"\n"]}
@@ -0,0 +1,147 @@
1
+ import { z } from 'zod';
2
+ import { a as AgencyV2Handle } from '../types-DOmT5DLV.js';
3
+
4
+ /**
5
+ * AIP-21 AGENCY.md frontmatter zod schema.
6
+ *
7
+ * Generated from `resources/aip-21/draft/AGENCY.schema.json` via
8
+ * json-schema-to-zod. Imported by both `define-agency-v2.ts` (TS path
9
+ * validation) and `manifest/index.ts` (.md path validation) so every
10
+ * field-level constraint runs in both authoring paths from a single
11
+ * source of truth — re-run scaffold-aip to refresh after spec changes.
12
+ *
13
+ * Cross-field rules (if/then/allOf in JSON Schema) don't translate
14
+ * cleanly and live in `define-agency-v2.ts`'s `validate(def)` instead.
15
+ */
16
+
17
+ declare const agencyV2FrontmatterSchema: z.ZodIntersection<z.ZodObject<{
18
+ schema: z.ZodLiteral<"agency.workspace/v2">;
19
+ name: z.ZodString;
20
+ title: z.ZodString;
21
+ description: z.ZodString;
22
+ version: z.ZodString;
23
+ extends: z.ZodOptional<z.ZodString>;
24
+ appliesTo: z.ZodOptional<z.ZodArray<z.ZodString>>;
25
+ identity: z.ZodOptional<z.ZodObject<{
26
+ legalEntity: z.ZodOptional<z.ZodString>;
27
+ legalName: z.ZodOptional<z.ZodString>;
28
+ taxId: z.ZodOptional<z.ZodString>;
29
+ jurisdiction: z.ZodOptional<z.ZodString>;
30
+ defaultCurrency: z.ZodOptional<z.ZodString>;
31
+ }, z.core.$strict>>;
32
+ executor: z.ZodOptional<z.ZodString>;
33
+ governance: z.ZodOptional<z.ZodString>;
34
+ knowledge: z.ZodOptional<z.ZodString>;
35
+ work: z.ZodOptional<z.ZodString>;
36
+ playbook: z.ZodOptional<z.ZodString>;
37
+ companies: z.ZodOptional<z.ZodString>;
38
+ collections: z.ZodDefault<z.ZodArray<z.ZodAny>>;
39
+ lifecycle: z.ZodOptional<z.ZodObject<{
40
+ enabled: z.ZodDefault<z.ZodBoolean>;
41
+ rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
42
+ id: z.ZodString;
43
+ when: z.ZodString;
44
+ forCollection: z.ZodString;
45
+ bubbleStatus: z.ZodString;
46
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
47
+ }, z.core.$strict>>>;
48
+ }, z.core.$strict>>;
49
+ scope: z.ZodOptional<z.ZodObject<{
50
+ containment: z.ZodOptional<z.ZodObject<{
51
+ enabled: z.ZodDefault<z.ZodBoolean>;
52
+ field: z.ZodDefault<z.ZodString>;
53
+ rules: z.ZodOptional<z.ZodObject<{
54
+ allowedKinds: z.ZodOptional<z.ZodArray<z.ZodString>>;
55
+ maxDepth: z.ZodOptional<z.ZodNumber>;
56
+ }, z.core.$strict>>;
57
+ }, z.core.$strict>>;
58
+ applicability: z.ZodOptional<z.ZodObject<{
59
+ enabled: z.ZodDefault<z.ZodBoolean>;
60
+ field: z.ZodDefault<z.ZodString>;
61
+ valueClass: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strict>>;
63
+ ownership: z.ZodOptional<z.ZodObject<{
64
+ enabled: z.ZodDefault<z.ZodBoolean>;
65
+ field: z.ZodDefault<z.ZodString>;
66
+ policy: z.ZodDefault<z.ZodEnum<{
67
+ strict: "strict";
68
+ inherit: "inherit";
69
+ open: "open";
70
+ }>>;
71
+ }, z.core.$strict>>;
72
+ }, z.core.$strict>>;
73
+ lints: z.ZodDefault<z.ZodArray<z.ZodObject<{
74
+ id: z.ZodString;
75
+ kind: z.ZodEnum<{
76
+ custom: "custom";
77
+ "stale-engagement": "stale-engagement";
78
+ "unsigned-agreement": "unsigned-agreement";
79
+ "overdue-invoice": "overdue-invoice";
80
+ "broken-procedure-ref": "broken-procedure-ref";
81
+ "orphan-across-collections": "orphan-across-collections";
82
+ "stale-tree": "stale-tree";
83
+ "broken-parent-ref": "broken-parent-ref";
84
+ "scope-mismatch": "scope-mismatch";
85
+ }>;
86
+ severity: z.ZodEnum<{
87
+ error: "error";
88
+ warn: "warn";
89
+ info: "info";
90
+ }>;
91
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
92
+ }, z.core.$strict>>>;
93
+ defaults: z.ZodOptional<z.ZodObject<{
94
+ workflow: z.ZodOptional<z.ZodString>;
95
+ approvalClass: z.ZodOptional<z.ZodString>;
96
+ auditMutations: z.ZodDefault<z.ZodBoolean>;
97
+ }, z.core.$strict>>;
98
+ engagement: z.ZodOptional<z.ZodObject<{
99
+ terms: z.ZodOptional<z.ZodObject<{
100
+ contractRequired: z.ZodDefault<z.ZodBoolean>;
101
+ defaultPaymentTerms: z.ZodOptional<z.ZodString>;
102
+ defaultCurrency: z.ZodOptional<z.ZodString>;
103
+ }, z.core.$strict>>;
104
+ }, z.core.$strict>>;
105
+ display: z.ZodOptional<z.ZodObject<{
106
+ homePage: z.ZodOptional<z.ZodString>;
107
+ defaultGrouping: z.ZodOptional<z.ZodEnum<{
108
+ kind: "kind";
109
+ engagement: "engagement";
110
+ status: "status";
111
+ counterparty: "counterparty";
112
+ }>>;
113
+ defaultView: z.ZodOptional<z.ZodEnum<{
114
+ list: "list";
115
+ board: "board";
116
+ timeline: "timeline";
117
+ dashboard: "dashboard";
118
+ }>>;
119
+ }, z.core.$strict>>;
120
+ metadata: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodAny>>;
121
+ }, z.core.$strict>, z.ZodAny>;
122
+ type AgencyV2Frontmatter = z.infer<typeof agencyV2FrontmatterSchema>;
123
+
124
+ /**
125
+ * AIP-21 AGENCY.md sidecar parser + manifest-to-handle constructor.
126
+ *
127
+ * Mirror of `@agentproto/tool/manifest` and `@agentproto/driver/manifest`:
128
+ * the .md provides metadata; the TS module supplies any spec-specific
129
+ * runtime bits (schemas, execute bodies, …) that can't live in
130
+ * frontmatter. Both inputs end up in `defineAgencyV2` so the cross-AIP
131
+ * invariants run uniformly.
132
+ *
133
+ *
134
+ * The frontmatter zod schema below was generated from
135
+ * `resources/aip-21/draft/AGENCY.schema.json` via json-schema-to-zod.
136
+ * Re-run scaffold-aip to refresh after spec changes (or hand-tune
137
+ * any constraint the converter doesn't capture cleanly).
138
+ */
139
+
140
+ interface AgencyV2Manifest {
141
+ frontmatter: AgencyV2Frontmatter;
142
+ body: string;
143
+ }
144
+ declare function parseAgencyV2Manifest(source: string): AgencyV2Manifest;
145
+ declare function agencyV2FromManifest(manifest: AgencyV2Manifest): AgencyV2Handle;
146
+
147
+ export { type AgencyV2Frontmatter, type AgencyV2Manifest, agencyV2FromManifest, agencyV2FrontmatterSchema, parseAgencyV2Manifest };
@@ -0,0 +1,28 @@
1
+ import { agencyV2FrontmatterSchema, defineAgencyV2 } from '../chunk-2EJ3V4IK.mjs';
2
+ export { agencyV2FrontmatterSchema } from '../chunk-2EJ3V4IK.mjs';
3
+ import matter from 'gray-matter';
4
+
5
+ /**
6
+ * @agentproto/agency-v2 v0.1.0-alpha
7
+ * AIP-21 AGENCY.md `defineAgencyV2` reference implementation.
8
+ */
9
+ function parseAgencyV2Manifest(source) {
10
+ const parsed = matter(source);
11
+ if (Object.keys(parsed.data).length === 0) {
12
+ throw new Error("parseAgencyV2Manifest: missing or empty frontmatter");
13
+ }
14
+ const result = agencyV2FrontmatterSchema.safeParse(parsed.data);
15
+ if (!result.success) {
16
+ throw new Error(
17
+ `parseAgencyV2Manifest: invalid frontmatter \u2014 ${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`
18
+ );
19
+ }
20
+ return { frontmatter: result.data, body: parsed.content };
21
+ }
22
+ function agencyV2FromManifest(manifest) {
23
+ return defineAgencyV2(manifest.frontmatter);
24
+ }
25
+
26
+ export { agencyV2FromManifest, parseAgencyV2Manifest };
27
+ //# sourceMappingURL=index.mjs.map
28
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/manifest/index.ts"],"names":[],"mappings":";;;;;;;;AA8BO,SAAS,sBAAsB,MAAA,EAAkC;AACtE,EAAA,MAAM,MAAA,GAAS,OAAO,MAAM,CAAA;AAC5B,EAAA,IAAI,OAAO,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AACzC,IAAA,MAAM,IAAI,MAAM,qDAAqD,CAAA;AAAA,EACvE;AACA,EAAA,MAAM,MAAA,GAAS,yBAAA,CAA0B,SAAA,CAAU,MAAA,CAAO,IAAI,CAAA;AAC9D,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,kDAAA,EAAgD,OAAO,KAAA,CAAM,MAAA,CAC1D,IAAI,CAAC,CAAA,KAAM,GAAG,CAAA,CAAE,IAAA,CAAK,KAAK,GAAG,CAAC,KAAK,CAAA,CAAE,OAAO,EAAE,CAAA,CAC9C,IAAA,CAAK,IAAI,CAAC,CAAA;AAAA,KACf;AAAA,EACF;AACA,EAAA,OAAO,EAAE,WAAA,EAAa,MAAA,CAAO,IAAA,EAAM,IAAA,EAAM,OAAO,OAAA,EAAQ;AAC1D;AAEO,SAAS,qBAAqB,QAAA,EAA4C;AAK/E,EAAA,OAAO,cAAA,CAAe,SAAS,WAA4C,CAAA;AAC7E","file":"index.mjs","sourcesContent":["/**\n * AIP-21 AGENCY.md sidecar parser + manifest-to-handle constructor.\n *\n * Mirror of `@agentproto/tool/manifest` and `@agentproto/driver/manifest`:\n * the .md provides metadata; the TS module supplies any spec-specific\n * runtime bits (schemas, execute bodies, …) that can't live in\n * frontmatter. Both inputs end up in `defineAgencyV2` so the cross-AIP\n * invariants run uniformly.\n *\n *\n * The frontmatter zod schema below was generated from\n * `resources/aip-21/draft/AGENCY.schema.json` via json-schema-to-zod.\n * Re-run scaffold-aip to refresh after spec changes (or hand-tune\n * any constraint the converter doesn't capture cleanly).\n */\n\nimport matter from \"gray-matter\"\nimport { agencyV2FrontmatterSchema, type AgencyV2Frontmatter } from \"../schema.js\"\nimport { defineAgencyV2 } from \"../define-agency-v2.js\"\nimport type { AgencyV2Definition, AgencyV2Handle } from \"../types.js\"\n\n// Re-export so consumers can import the schema + inferred type either\n// from \"@@agentproto/agency-v2/manifest\" or directly from \"@@agentproto/agency-v2/schema\".\nexport { agencyV2FrontmatterSchema, type AgencyV2Frontmatter }\n\nexport interface AgencyV2Manifest {\n frontmatter: AgencyV2Frontmatter\n body: string\n}\n\nexport function parseAgencyV2Manifest(source: string): AgencyV2Manifest {\n const parsed = matter(source)\n if (Object.keys(parsed.data).length === 0) {\n throw new Error(\"parseAgencyV2Manifest: missing or empty frontmatter\")\n }\n const result = agencyV2FrontmatterSchema.safeParse(parsed.data)\n if (!result.success) {\n throw new Error(\n `parseAgencyV2Manifest: invalid frontmatter — ${result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \")}`,\n )\n }\n return { frontmatter: result.data, body: parsed.content }\n}\n\nexport function agencyV2FromManifest(manifest: AgencyV2Manifest): AgencyV2Handle {\n // The zod-validated frontmatter is structurally compatible with\n // AgencyV2Definition; the cast pins the typing once the manifest\n // schema and the TS interface diverge (e.g. handle has frozen fields\n // a literal config doesn't carry yet).\n return defineAgencyV2(manifest.frontmatter as unknown as AgencyV2Definition)\n}\n"]}
@@ -0,0 +1,556 @@
1
+ /**
2
+ * AIP-21 AgencyV2Definition + AgencyV2Handle.
3
+ *
4
+ * `AgencyV2Definition` was generated from
5
+ * `resources/aip-21/draft/AGENCY.schema.json` via json-schema-to-typescript.
6
+ * `AgencyV2Handle` is the readonly view of the same shape; tighten it
7
+ * by hand for fields that get defaults applied in build().
8
+ */
9
+ /**
10
+ * Validates the YAML frontmatter portion of an AIP-21 AGENCY.md (workspace root or per-context view). The single doctype 'agency.workspace/v2' is used in both modes; the host distinguishes by checking whether `extends` is set. Per-doctype schemas (service, engagement, agreement, deliverable, invoice, counterparty, procedure, pricing-model, routine, capacity) are delegated to AIP-18 (COLLECTION.md / ITEM.md).
11
+ */
12
+ type AgencyV2Definition = {
13
+ [k: string]: unknown;
14
+ } & {
15
+ /**
16
+ * Discriminator for the AIP-21 workspace doctype.
17
+ */
18
+ schema: "agency.workspace/v2";
19
+ /**
20
+ * Stable kebab-case identifier for the agency or view.
21
+ */
22
+ name: string;
23
+ /**
24
+ * Human-readable agency title.
25
+ */
26
+ title: string;
27
+ /**
28
+ * One-paragraph statement of purpose: what this agency does and who it serves.
29
+ */
30
+ description: string;
31
+ /**
32
+ * Semantic version of the WORKSPACE shape. Bump on collection / scope / lifecycle / lint / defaults changes. Independent of the agency's content version.
33
+ */
34
+ version: string;
35
+ /**
36
+ * OPTIONAL — relative path to a parent AGENCY.md. Presence makes the manifest a VIEW; absence makes it a WORKSPACE ROOT. Recursive composition; maximum chain depth is 8.
37
+ */
38
+ extends?: string;
39
+ /**
40
+ * OPTIONAL — list of consumers this VIEW adapts the agency for. Hosts MUST refuse the view if any binding does not resolve. Not inherited; views declare their own scope.
41
+ */
42
+ appliesTo?: string[];
43
+ /**
44
+ * Commercial-flavored identity block. All fields optional; agencies operating as a sole operator with no counterparty billing may omit the block entirely.
45
+ */
46
+ identity?: {
47
+ /**
48
+ * OPTIONAL — AIP-6 ref to the company that legally signs agreements and issues invoices. When set, hosts SHOULD resolve this ref to populate legalName and taxId from the AIP-6 record.
49
+ */
50
+ legalEntity?: string;
51
+ /**
52
+ * OPTIONAL — display string for the legal entity name. Used when legalEntity is absent or to override the AIP-6 record's legalName.
53
+ */
54
+ legalName?: string;
55
+ /**
56
+ * OPTIONAL — tax identifier (VAT, EIN, GST, etc.). Hosts MUST treat this string as opaque; format validation belongs to per-jurisdiction tooling.
57
+ */
58
+ taxId?: string;
59
+ /**
60
+ * OPTIONAL — primary jurisdiction the agency operates under, as ISO 3166-1 alpha-2 (e.g. FR, US, GB, DE).
61
+ */
62
+ jurisdiction?: string;
63
+ /**
64
+ * OPTIONAL — default currency for new invoices, as ISO 4217 (e.g. EUR, USD, GBP). Per-engagement overrides take precedence.
65
+ */
66
+ defaultCurrency?: string;
67
+ };
68
+ /**
69
+ * OPTIONAL — AIP-9 default executor operator. The host activates this operator when an item with no explicit assignee surfaces.
70
+ */
71
+ executor?: string;
72
+ /**
73
+ * OPTIONAL — AIP-7 policy or audit binding. May be a path to an AIP-7 policy file or a ws:// ref. Status-transition approvals, signature gates on agreements, and audit log routing flow through this ref. Agreements MUST be signed; the default policy lives here.
74
+ */
75
+ governance?: string;
76
+ /**
77
+ * OPTIONAL — AIP-10 KNOWLEDGE.md ref. Wiki this agency refers to (case studies, prior-art, methodology).
78
+ */
79
+ knowledge?: string;
80
+ /**
81
+ * OPTIONAL — AIP-20 work workspace binding. Items in `deliverable` MAY be tracked as work items in the bound workspace.
82
+ */
83
+ work?: string;
84
+ /**
85
+ * OPTIONAL — AIP-12 active playbook. Governs the routine plays this agency runs.
86
+ */
87
+ playbook?: string;
88
+ /**
89
+ * OPTIONAL — AIP-6 companies root. Resolution root for `counterparty` items: a counterparty's companyRef resolves under this binding.
90
+ */
91
+ companies?: string;
92
+ /**
93
+ * Collections enabled by this agency. Three forms supported: inline (full COLLECTION.md frontmatter), file ref, or registry import. Merge-by-effective-name (alias if set, otherwise the collection's name) across the extends chain.
94
+ */
95
+ collections?: CollectionEntry[];
96
+ /**
97
+ * Engagement lifecycle helpers — workspace-level rules for cross-collection state propagation. The AIP-21 distinctive contribution.
98
+ */
99
+ lifecycle?: {
100
+ /**
101
+ * Whether cross-collection lifecycle propagation is active. When false, no lifecycle rules fire — items keep their stored statuses regardless of related items.
102
+ */
103
+ enabled?: boolean;
104
+ /**
105
+ * Cross-collection lifecycle rules. Merge-by-id vs parent. Hosts MUST detect graph cycles in the (forCollection, sourceCollection) edge set and refuse with agency_lifecycle_cycle (HARD).
106
+ */
107
+ rules?: {
108
+ /**
109
+ * Stable kebab-case rule id. Merge key when composing across extends.
110
+ */
111
+ id: string;
112
+ /**
113
+ * Predicate id from the recognised vocabulary. Custom predicates are host-defined keyed by `id`.
114
+ */
115
+ when: string;
116
+ /**
117
+ * Effective name of the collection whose items receive the bubbled status. MUST appear in the workspace's merged collections array.
118
+ */
119
+ forCollection: string;
120
+ /**
121
+ * Status id to set on the target item when the predicate holds. MUST exist on the forCollection's state machine.
122
+ */
123
+ bubbleStatus: string;
124
+ /**
125
+ * Predicate parameters. Common keys: sourceCollection (collection whose items the predicate inspects), linkField (field on source items pointing at the target), terminalStatuses (subset of terminal statuses to count), statusEquals (specific status to match).
126
+ */
127
+ params?: {
128
+ [k: string]: unknown;
129
+ };
130
+ }[];
131
+ };
132
+ /**
133
+ * Workspace-level scope axes — three orthogonal axes (containment / applicability / ownership) declared once per agency.
134
+ */
135
+ scope?: {
136
+ /**
137
+ * Containment axis (parent/child).
138
+ */
139
+ containment?: {
140
+ /**
141
+ * Whether the containment axis is active. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false (would orphan items). Refusal: agency_scope_disable (HARD).
142
+ */
143
+ enabled?: boolean;
144
+ /**
145
+ * Item field name carrying the containment ref.
146
+ */
147
+ field?: string;
148
+ /**
149
+ * OPTIONAL containment constraints.
150
+ */
151
+ rules?: {
152
+ /**
153
+ * OPTIONAL — collection names allowed as containment parents.
154
+ */
155
+ allowedKinds?: string[];
156
+ /**
157
+ * OPTIONAL — maximum containment depth.
158
+ */
159
+ maxDepth?: number;
160
+ };
161
+ };
162
+ /**
163
+ * Applicability axis (who the item is about / scoped to).
164
+ */
165
+ applicability?: {
166
+ /**
167
+ * Whether the applicability axis is active.
168
+ */
169
+ enabled?: boolean;
170
+ /**
171
+ * Item field name carrying the applicability ref list.
172
+ */
173
+ field?: string;
174
+ /**
175
+ * Class of refs the field accepts. Recognised classes: client, market, service, company, role, role-and-company, operator. ONE-WAY SWITCH: once set at any ancestor, descendants MUST NOT change. Refusal: agency_scope_value_class_drift (HARD).
176
+ */
177
+ valueClass?: string;
178
+ };
179
+ /**
180
+ * Ownership axis (who is doing the item).
181
+ */
182
+ ownership?: {
183
+ /**
184
+ * Whether the ownership axis is active.
185
+ */
186
+ enabled?: boolean;
187
+ /**
188
+ * Workspace-level default item field name carrying the ownership ref.
189
+ */
190
+ field?: string;
191
+ /**
192
+ * Workspace-level ownership policy. 'strict' requires every collection's ownership.required to be true; 'inherit' delegates; 'open' permits any collection to omit ownership.
193
+ */
194
+ policy?: "strict" | "inherit" | "open";
195
+ };
196
+ };
197
+ /**
198
+ * Workspace-spanning lints. Merge-by-id vs parent.
199
+ */
200
+ lints?: {
201
+ /**
202
+ * Stable kebab-case lint id. Merge key when composing with extends parent.
203
+ */
204
+ id: string;
205
+ /**
206
+ * Workspace-spanning lint algorithm. AIP-18 per-collection lints (missing-owner, overdue, required-field, etc.) live on COLLECTION.md and are NOT redeclared here. 'custom' delegates to a host-defined check identified by `id`.
207
+ */
208
+ kind: "stale-engagement" | "unsigned-agreement" | "overdue-invoice" | "broken-procedure-ref" | "orphan-across-collections" | "stale-tree" | "broken-parent-ref" | "scope-mismatch" | "custom";
209
+ /**
210
+ * Lint severity. Children may soften; governance policies MAY forbid softening below `error`.
211
+ */
212
+ severity: "error" | "warn" | "info";
213
+ /**
214
+ * Kind-specific parameters.
215
+ */
216
+ params?: {
217
+ [k: string]: unknown;
218
+ };
219
+ }[];
220
+ /**
221
+ * Routine workflow defaults. Composes with AIP-15.
222
+ */
223
+ defaults?: {
224
+ /**
225
+ * OPTIONAL — default AIP-15 WORKFLOW.md path or ref.
226
+ */
227
+ workflow?: string;
228
+ /**
229
+ * Approval class for mutations. 'auto' = no gate; 'always' = every mutation requires approval; 'on-mutate' = approval on field-level mutations; 'policy:<ref>' = delegate to an AIP-7 policy.
230
+ */
231
+ approvalClass?: string;
232
+ /**
233
+ * Whether mutations are audited. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false. Refusal: agency_audit_downgrade (HARD).
234
+ */
235
+ auditMutations?: boolean;
236
+ };
237
+ /**
238
+ * Engagement-specific terms (AIP-21 distinctive).
239
+ */
240
+ engagement?: {
241
+ /**
242
+ * Default commercial terms applied to new engagement and invoice items.
243
+ */
244
+ terms?: {
245
+ /**
246
+ * Whether engagement items require a corresponding agreement item. ONE-WAY SWITCH: once true at any ancestor, descendants MUST NOT set false (commercial protection against engagements without paperwork). Refusal: agency_contract_required_downgrade (HARD).
247
+ */
248
+ contractRequired?: boolean;
249
+ /**
250
+ * OPTIONAL — default payment terms for new invoices. Common values: net-15, net-30, net-60, due-on-receipt, prepaid. Custom kebab-case strings permitted.
251
+ */
252
+ defaultPaymentTerms?: string;
253
+ /**
254
+ * OPTIONAL — default currency for engagement-derived invoices, as ISO 4217. Falls back to identity.defaultCurrency if unset.
255
+ */
256
+ defaultCurrency?: string;
257
+ };
258
+ };
259
+ /**
260
+ * Display hints for UIs that render the agency. Runtime-agnostic.
261
+ */
262
+ display?: {
263
+ /**
264
+ * OPTIONAL — id of the item to use as the agency landing page.
265
+ */
266
+ homePage?: string;
267
+ /**
268
+ * Default grouping for list views.
269
+ */
270
+ defaultGrouping?: "kind" | "status" | "counterparty" | "engagement";
271
+ /**
272
+ * Default rendering mode.
273
+ */
274
+ defaultView?: "list" | "board" | "timeline" | "dashboard";
275
+ };
276
+ /**
277
+ * Vendor-specific extensions, namespaced under <vendor>. Deep-merged across the extends chain. MUST NOT change the meaning of any spec field.
278
+ */
279
+ metadata?: {
280
+ [k: string]: unknown;
281
+ };
282
+ };
283
+ /**
284
+ * One collection declaration. Either an inline AIP-18 collection schema, or a ref (path or ws:// URI) optionally aliased and version-pinned.
285
+ */
286
+ type CollectionEntry = CollectionInline | CollectionRef;
287
+ /**
288
+ * Full AIP-18 collection.schema/v1 frontmatter, parsed in-place. The host registers the collection directly via AIP-18's defineCollection without loading a separate file.
289
+ */
290
+ type Schema = {
291
+ [k: string]: unknown;
292
+ } & {
293
+ /**
294
+ * Discriminator for a collection definition.
295
+ */
296
+ schema: "collection.schema/v1";
297
+ /**
298
+ * Stable kebab-case identifier. Items reference this name via their `collection:` field.
299
+ */
300
+ name: string;
301
+ /**
302
+ * Human-readable collection title.
303
+ */
304
+ title: string;
305
+ /**
306
+ * One-paragraph statement of purpose: what this collection captures and when an item belongs here vs another collection.
307
+ */
308
+ description: string;
309
+ /**
310
+ * Semantic version of the SHAPE. Bump on field/status/lint changes. Independent of the collection's content.
311
+ */
312
+ version: string;
313
+ /**
314
+ * OPTIONAL — relative path to a parent COLLECTION.md. Recursive composition; maximum chain depth is 8.
315
+ */
316
+ extends?: string;
317
+ /**
318
+ * OPTIONAL — list of consumers this collection adapts for. Hosts MUST refuse if any binding does not resolve. Not inherited; each child declares its own scope.
319
+ */
320
+ appliesTo?: string[];
321
+ /**
322
+ * Item field schema. Merge-by-name vs parent: a child entry with the same `name` replaces the parent's (subject to type-drift refusal); new names are appended.
323
+ */
324
+ fields?: FieldDef[];
325
+ /**
326
+ * Status state machine. Merge-by-id vs parent. Children may add statuses, mark inherited statuses terminal, or narrow `transitionsTo`; they MUST NOT remove an inherited status.
327
+ */
328
+ statuses?: {
329
+ /**
330
+ * Stable kebab-case status id. Merge key when composing.
331
+ */
332
+ id: string;
333
+ /**
334
+ * Human-readable status label.
335
+ */
336
+ label: string;
337
+ /**
338
+ * Whether items in this status are considered closed. Lints like `overdue` typically skip terminal statuses.
339
+ */
340
+ terminal?: boolean;
341
+ /**
342
+ * OPTIONAL — allowed next status ids. If omitted, all transitions are permitted.
343
+ */
344
+ transitionsTo?: string[];
345
+ }[];
346
+ /**
347
+ * OPTIONAL — default status assigned to new items. MUST refer to a status declared (locally or inherited) by this collection.
348
+ */
349
+ initialStatus?: string;
350
+ /**
351
+ * Ownership rules. Each leaf field overrides independently across the chain.
352
+ */
353
+ ownership?: {
354
+ /**
355
+ * How many owners an item may carry. `none` = no ownership concept; `single` = one owner; `multiple` = list of owners.
356
+ */
357
+ cardinality?: "none" | "single" | "multiple";
358
+ /**
359
+ * Item field name that holds the owner ref.
360
+ */
361
+ role?: string;
362
+ /**
363
+ * Whether items MUST declare an owner.
364
+ */
365
+ required?: boolean;
366
+ };
367
+ /**
368
+ * Deadline rules. Each leaf field overrides independently.
369
+ */
370
+ deadline?: {
371
+ /**
372
+ * Deadline shape. `none` = no deadline concept; `target-date` = single date; `window` = start+end; `recurrent` = repeating.
373
+ */
374
+ kind?: "none" | "target-date" | "window" | "recurrent";
375
+ /**
376
+ * Whether items MUST declare a deadline value.
377
+ */
378
+ required?: boolean;
379
+ /**
380
+ * Item field name that holds the deadline value.
381
+ */
382
+ fieldName?: string;
383
+ };
384
+ /**
385
+ * Lint rules. Merge-by-id vs parent.
386
+ */
387
+ lints?: {
388
+ /**
389
+ * Stable kebab-case lint id. Merge key when composing.
390
+ */
391
+ id: string;
392
+ /**
393
+ * Lint algorithm. `custom` delegates to a host-defined check identified by `id`.
394
+ */
395
+ kind: "missing-owner" | "overdue" | "orphan" | "broken-ref" | "stale" | "required-field" | "custom";
396
+ /**
397
+ * Always '*' — items belong to one collection, so the lint always applies to all items of this collection. The field is preserved for symmetry with AIP-10's lint shape.
398
+ */
399
+ appliesTo: "*";
400
+ /**
401
+ * Lint severity. Children may soften; governance policies MAY forbid softening below `error`.
402
+ */
403
+ severity: "error" | "warn" | "info";
404
+ /**
405
+ * Kind-specific parameters. e.g. { days: 30 } for `stale`; { field: 'severity' } for `required-field`.
406
+ */
407
+ params?: {
408
+ [k: string]: unknown;
409
+ };
410
+ }[];
411
+ /**
412
+ * Item identity & filing rules.
413
+ */
414
+ identity?: {
415
+ /**
416
+ * How to derive an item's slug. Either a field name (e.g. 'title'), the literal 'random', the literal 'sequence', or 'hash:<comma-separated-source-fields>' (e.g. 'hash:title,createdAt').
417
+ */
418
+ slugSource?: string;
419
+ /**
420
+ * Template for where items are filed on disk. Tokens: {collection}, {slug}, {year}, {month}. e.g. 'items/{collection}/{slug}.md'.
421
+ */
422
+ filingPath?: string;
423
+ };
424
+ /**
425
+ * Vendor-specific extensions, namespaced under <vendor>. Deep-merged across the extends chain.
426
+ */
427
+ metadata?: {
428
+ [k: string]: unknown;
429
+ };
430
+ };
431
+ /**
432
+ * Inline collection declaration. Full AIP-18 schema embedded; hosts MUST validate it against the AIP-18 COLLECTION schema before registration.
433
+ */
434
+ interface CollectionInline {
435
+ inline: Schema;
436
+ }
437
+ /**
438
+ * Definition of one field on a collection's item schema. Merge-by-name. Type drift between parent and child is HARD refused.
439
+ */
440
+ interface FieldDef {
441
+ /**
442
+ * kebab-or-camel-case field name. Merge key when composing.
443
+ */
444
+ name: string;
445
+ /**
446
+ * Field type. Drift across composition (parent string -> child number) is HARD refused (`collection_field_type_drift`).
447
+ */
448
+ type: "string" | "number" | "boolean" | "enum" | "date" | "datetime" | "text" | "url" | "ref" | "array";
449
+ /**
450
+ * Whether items MUST declare this field. A child may narrow false -> true; loosening true -> false is permitted (it removes a constraint without invalidating instances).
451
+ */
452
+ required?: boolean;
453
+ /**
454
+ * Prose describing what the field captures.
455
+ */
456
+ description?: string;
457
+ /**
458
+ * Required when type=enum. Children may narrow to a subset; widening to a superset is permitted (it does not invalidate instances).
459
+ */
460
+ enum?: string[];
461
+ items?: FieldDef1;
462
+ /**
463
+ * Required when type=ref. The target collection's `name`. Hosts validate that ref values point at items of this collection.
464
+ */
465
+ refKind?: string;
466
+ /**
467
+ * OPTIONAL regex constraint. Only valid when type=string.
468
+ */
469
+ pattern?: string;
470
+ /**
471
+ * OPTIONAL minimum. For type=number: minimum value. For type=array: minimum length.
472
+ */
473
+ min?: number;
474
+ /**
475
+ * OPTIONAL maximum. For type=number: maximum value. For type=array: maximum length.
476
+ */
477
+ max?: number;
478
+ /**
479
+ * OPTIONAL named format. Common values: email, uri, semver, uuid, slug. Only valid when type=string. Hosts MAY interpret unknown formats as advisory.
480
+ */
481
+ format?: string;
482
+ /**
483
+ * OPTIONAL deprecation flag. A child may set false to mark an inherited field deprecated; the host preserves the field in the resolved schema (so existing items still validate) but flags new uses via lint. Setting enabled:false on a field a child does not inherit is invalid.
484
+ */
485
+ enabled?: boolean;
486
+ }
487
+ /**
488
+ * Required when type=array. Recursive shape — describes the inner item type.
489
+ */
490
+ interface FieldDef1 {
491
+ /**
492
+ * kebab-or-camel-case field name. Merge key when composing.
493
+ */
494
+ name: string;
495
+ /**
496
+ * Field type. Drift across composition (parent string -> child number) is HARD refused (`collection_field_type_drift`).
497
+ */
498
+ type: "string" | "number" | "boolean" | "enum" | "date" | "datetime" | "text" | "url" | "ref" | "array";
499
+ /**
500
+ * Whether items MUST declare this field. A child may narrow false -> true; loosening true -> false is permitted (it removes a constraint without invalidating instances).
501
+ */
502
+ required?: boolean;
503
+ /**
504
+ * Prose describing what the field captures.
505
+ */
506
+ description?: string;
507
+ /**
508
+ * Required when type=enum. Children may narrow to a subset; widening to a superset is permitted (it does not invalidate instances).
509
+ */
510
+ enum?: string[];
511
+ items?: FieldDef1;
512
+ /**
513
+ * Required when type=ref. The target collection's `name`. Hosts validate that ref values point at items of this collection.
514
+ */
515
+ refKind?: string;
516
+ /**
517
+ * OPTIONAL regex constraint. Only valid when type=string.
518
+ */
519
+ pattern?: string;
520
+ /**
521
+ * OPTIONAL minimum. For type=number: minimum value. For type=array: minimum length.
522
+ */
523
+ min?: number;
524
+ /**
525
+ * OPTIONAL maximum. For type=number: maximum value. For type=array: maximum length.
526
+ */
527
+ max?: number;
528
+ /**
529
+ * OPTIONAL named format. Common values: email, uri, semver, uuid, slug. Only valid when type=string. Hosts MAY interpret unknown formats as advisory.
530
+ */
531
+ format?: string;
532
+ /**
533
+ * OPTIONAL deprecation flag. A child may set false to mark an inherited field deprecated; the host preserves the field in the resolved schema (so existing items still validate) but flags new uses via lint. Setting enabled:false on a field a child does not inherit is invalid.
534
+ */
535
+ enabled?: boolean;
536
+ }
537
+ /**
538
+ * Collection ref declaration. Either a file path or a registry URI.
539
+ */
540
+ interface CollectionRef {
541
+ /**
542
+ * Either a relative path to a COLLECTION.md (file ref) or a ws://collections/<slug> URI (registry import).
543
+ */
544
+ ref: string;
545
+ /**
546
+ * OPTIONAL — workspace-local name to expose the collection under. Items in this workspace reference the alias, not the upstream name. Two collections resolving to the same effective name is a HARD failure: agency_collection_alias_conflict.
547
+ */
548
+ alias?: string;
549
+ /**
550
+ * OPTIONAL — semver range (e.g. "1.x", "^1.2", "1.2.0"). When set, schema bumps outside the range fail with collection_item_schema_pinned_drift (HARD) at item load time.
551
+ */
552
+ version?: string;
553
+ }
554
+ type AgencyV2Handle = Readonly<AgencyV2Definition>;
555
+
556
+ export type { AgencyV2Definition as A, AgencyV2Handle as a };
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@agentproto/agency-v2",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "@agentproto/agency-v2 — AIP-21 AGENCY.md reference implementation. A workspace-only successor to AIP-8 that drops the eleven hardcoded agency doctypes (service, engagement, agreement, deliverable, invoice, counterparty, procedure, pricing-model, routine, capacity, agency) and delegates all per-doctype schema work to AIP-18 collections — owning only the workspace root manifest, the engagement lifecycle helpers that span collections, scope axes, and cross-AIP composition with strong governance and work bindings.",
5
+ "keywords": [
6
+ "agentproto",
7
+ "aip-21",
8
+ "agency-v2",
9
+ "defineAgencyV2",
10
+ "open-standard",
11
+ "agentic"
12
+ ],
13
+ "homepage": "https://agentproto.sh/docs/aip-21",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/agentproto/ts",
17
+ "directory": "packages/agency-v2"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/agentproto/ts/issues"
21
+ },
22
+ "license": "MIT",
23
+ "type": "module",
24
+ "main": "dist/index.mjs",
25
+ "module": "dist/index.mjs",
26
+ "types": "dist/index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.mjs",
31
+ "default": "./dist/index.mjs"
32
+ },
33
+ "./manifest": {
34
+ "types": "./dist/manifest/index.d.ts",
35
+ "import": "./dist/manifest/index.mjs",
36
+ "default": "./dist/manifest/index.mjs"
37
+ },
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "README.md",
43
+ "LICENSE"
44
+ ],
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "dependencies": {
49
+ "gray-matter": "^4.0.3",
50
+ "zod": "^4.4.3",
51
+ "@agentproto/define-doctype": "0.1.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^25.6.2",
55
+ "tsup": "^8.5.1",
56
+ "typescript": "^5.9.3",
57
+ "vitest": "^3.2.4",
58
+ "@agentproto/tooling": "0.1.0-alpha.0"
59
+ },
60
+ "scripts": {
61
+ "dev": "tsup --watch",
62
+ "build": "tsup",
63
+ "clean": "rm -rf dist",
64
+ "check-types": "tsc --noEmit",
65
+ "test": "vitest run --passWithNoTests",
66
+ "test:watch": "vitest"
67
+ }
68
+ }