@agentproto/governance 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.
@@ -0,0 +1,73 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Renderer wrapper for the `governance.signing-portal` canvakit template.
5
+ *
6
+ * The template is a self-contained HTML page that presents a `typed_name`
7
+ * signing form. The host application is responsible for:
8
+ * 1. Resolving the artifact + computing its SHA-256 documentHash.
9
+ * 2. Generating a one-time nonce + signing URL.
10
+ * 3. Receiving the form POST + writing the signature.json via
11
+ * @agentproto/governance `signArtifact` runtime helper.
12
+ *
13
+ * This module does NOT call canvakit directly — it just exposes the template
14
+ * id, the variable schema, and a builder helper. Apps wire it to their canvakit
15
+ * renderer (e.g., @canvakit/core).
16
+ */
17
+
18
+ declare const SIGNING_PORTAL_TEMPLATE_ID: "governance.signing-portal";
19
+ /** Path to the bundled .canvakit.html template (relative to the package root). */
20
+ declare const SIGNING_PORTAL_TEMPLATE_PATH: "src/spec/canvakit-templates/governance.signing-portal/template.canvakit.html";
21
+ declare const signingPortalVariablesSchema: z.ZodObject<{
22
+ artifactPath: z.ZodString;
23
+ artifactTitle: z.ZodString;
24
+ artifactExcerpt: z.ZodOptional<z.ZodString>;
25
+ documentHash: z.ZodString;
26
+ signerKind: z.ZodEnum<{
27
+ operator: "operator";
28
+ user: "user";
29
+ counterparty: "counterparty";
30
+ agent: "agent";
31
+ external: "external";
32
+ }>;
33
+ signerSlug: z.ZodString;
34
+ signerName: z.ZodOptional<z.ZodString>;
35
+ signerEmail: z.ZodOptional<z.ZodEmail>;
36
+ nonce: z.ZodString;
37
+ signUrl: z.ZodString;
38
+ agencyName: z.ZodOptional<z.ZodString>;
39
+ }, z.core.$strip>;
40
+ type SigningPortalVariables = z.infer<typeof signingPortalVariablesSchema>;
41
+ /** Build the variable bag for the canvakit template, applying defaults for absent fields. */
42
+ declare function signingPortalVariables(input: SigningPortalVariables): Record<string, string>;
43
+
44
+ /**
45
+ * Renderer wrapper for the `governance.signature-card` canvakit template.
46
+ *
47
+ * Stub — Phase 4. Will display a single signature event as a compact card
48
+ * (signer, method, timestamp, document hash truncated, evidence summary).
49
+ *
50
+ * For now, callers MAY render their own UI directly from a Signature object.
51
+ */
52
+ declare const SIGNATURE_CARD_TEMPLATE_ID: "governance.signature-card";
53
+ declare const SIGNATURE_CARD_TEMPLATE_PATH: "src/spec/canvakit-templates/governance.signature-card/template.canvakit.html";
54
+
55
+ /**
56
+ * Renderer wrapper for the `governance.audit-timeline` canvakit template.
57
+ *
58
+ * Stub — Phase 4. Will display an audit-log.jsonl as a vertical timeline
59
+ * (chronological, color-coded by action verb, with hash-chain integrity badge).
60
+ */
61
+ declare const AUDIT_TIMELINE_TEMPLATE_ID: "governance.audit-timeline";
62
+ declare const AUDIT_TIMELINE_TEMPLATE_PATH: "src/spec/canvakit-templates/governance.audit-timeline/template.canvakit.html";
63
+
64
+ /**
65
+ * Renderer wrapper for the `governance.policy-summary` canvakit template.
66
+ *
67
+ * Stub — Phase 4. Will render a POLICY.md as a human-readable summary
68
+ * (caps, threshold, required signers, escalation chain).
69
+ */
70
+ declare const POLICY_SUMMARY_TEMPLATE_ID: "governance.policy-summary";
71
+ declare const POLICY_SUMMARY_TEMPLATE_PATH: "src/spec/canvakit-templates/governance.policy-summary/template.canvakit.html";
72
+
73
+ export { AUDIT_TIMELINE_TEMPLATE_ID, AUDIT_TIMELINE_TEMPLATE_PATH, POLICY_SUMMARY_TEMPLATE_ID, POLICY_SUMMARY_TEMPLATE_PATH, SIGNATURE_CARD_TEMPLATE_ID, SIGNATURE_CARD_TEMPLATE_PATH, SIGNING_PORTAL_TEMPLATE_ID, SIGNING_PORTAL_TEMPLATE_PATH, type SigningPortalVariables, signingPortalVariables, signingPortalVariablesSchema };
@@ -0,0 +1,64 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * @agentproto/governance v0.1.0-alpha
5
+ * agentgovernance/v1 — universal contractual approval framework.
6
+ * Vendor-neutral. Filesystem-first. Third-party verifiable.
7
+ */
8
+
9
+ var SIGNING_PORTAL_TEMPLATE_ID = "governance.signing-portal";
10
+ var SIGNING_PORTAL_TEMPLATE_PATH = "src/spec/canvakit-templates/governance.signing-portal/template.canvakit.html";
11
+ var signingPortalVariablesSchema = z.object({
12
+ /** Workspace-relative path to the artifact being signed. */
13
+ artifactPath: z.string().min(1),
14
+ /** Human-readable title to display (e.g., agreement title). */
15
+ artifactTitle: z.string().min(1),
16
+ /** Optional short excerpt of the artifact body (rendered above the form). */
17
+ artifactExcerpt: z.string().optional(),
18
+ /** SHA-256 hex of the artifact bytes; same value gets stored in signature.json. */
19
+ documentHash: z.string().regex(/^[a-f0-9]{64}$/),
20
+ /** Canonical signer kind (operator, user, counterparty, agent, external). */
21
+ signerKind: z.enum(["operator", "user", "counterparty", "agent", "external"]),
22
+ /** Canonical signer slug (without the `<kind>:` prefix). */
23
+ signerSlug: z.string().min(1),
24
+ /** Pre-filled name (if known); leave blank for a fresh portal session. */
25
+ signerName: z.string().optional(),
26
+ signerEmail: z.email().optional(),
27
+ /** One-shot nonce token; signing endpoint MUST validate + invalidate on submit. */
28
+ nonce: z.string().min(1),
29
+ /** URL the form POSTs to. The endpoint receives a form-encoded body. */
30
+ signUrl: z.string().min(1),
31
+ /** Optional agency / company name shown in the lead paragraph. */
32
+ agencyName: z.string().optional()
33
+ });
34
+ function signingPortalVariables(input) {
35
+ return {
36
+ artifactPath: input.artifactPath,
37
+ artifactTitle: input.artifactTitle,
38
+ artifactExcerpt: input.artifactExcerpt ?? "",
39
+ documentHash: input.documentHash,
40
+ signerKind: input.signerKind,
41
+ signerSlug: input.signerSlug,
42
+ signerName: input.signerName ?? "",
43
+ signerEmail: input.signerEmail ?? "",
44
+ nonce: input.nonce,
45
+ signUrl: input.signUrl,
46
+ agencyName: input.agencyName ?? ""
47
+ };
48
+ }
49
+
50
+ // src/spec/renderers/signature-card.ts
51
+ var SIGNATURE_CARD_TEMPLATE_ID = "governance.signature-card";
52
+ var SIGNATURE_CARD_TEMPLATE_PATH = "src/spec/canvakit-templates/governance.signature-card/template.canvakit.html";
53
+
54
+ // src/spec/renderers/audit-timeline.ts
55
+ var AUDIT_TIMELINE_TEMPLATE_ID = "governance.audit-timeline";
56
+ var AUDIT_TIMELINE_TEMPLATE_PATH = "src/spec/canvakit-templates/governance.audit-timeline/template.canvakit.html";
57
+
58
+ // src/spec/renderers/policy-summary.ts
59
+ var POLICY_SUMMARY_TEMPLATE_ID = "governance.policy-summary";
60
+ var POLICY_SUMMARY_TEMPLATE_PATH = "src/spec/canvakit-templates/governance.policy-summary/template.canvakit.html";
61
+
62
+ export { AUDIT_TIMELINE_TEMPLATE_ID, AUDIT_TIMELINE_TEMPLATE_PATH, POLICY_SUMMARY_TEMPLATE_ID, POLICY_SUMMARY_TEMPLATE_PATH, SIGNATURE_CARD_TEMPLATE_ID, SIGNATURE_CARD_TEMPLATE_PATH, SIGNING_PORTAL_TEMPLATE_ID, SIGNING_PORTAL_TEMPLATE_PATH, signingPortalVariables, signingPortalVariablesSchema };
63
+ //# sourceMappingURL=index.mjs.map
64
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/spec/renderers/signing-portal.ts","../../src/spec/renderers/signature-card.ts","../../src/spec/renderers/audit-timeline.ts","../../src/spec/renderers/policy-summary.ts"],"names":[],"mappings":";;;;;;;;AAiBO,IAAM,0BAAA,GAA6B;AAGnC,IAAM,4BAAA,GACX;AAEK,IAAM,4BAAA,GAA+B,EAAE,MAAA,CAAO;AAAA;AAAA,EAEnD,YAAA,EAAc,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA;AAAA,EAE9B,aAAA,EAAe,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA;AAAA,EAE/B,eAAA,EAAiB,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAErC,YAAA,EAAc,CAAA,CAAE,MAAA,EAAO,CAAE,MAAM,gBAAgB,CAAA;AAAA;AAAA,EAE/C,UAAA,EAAY,EAAE,IAAA,CAAK,CAAC,YAAY,MAAA,EAAQ,cAAA,EAAgB,OAAA,EAAS,UAAU,CAAC,CAAA;AAAA;AAAA,EAE5E,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA;AAAA,EAE5B,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAChC,WAAA,EAAa,CAAA,CAAE,KAAA,EAAM,CAAE,QAAA,EAAS;AAAA;AAAA,EAEhC,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA;AAAA,EAEvB,OAAA,EAAS,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA;AAAA,EAEzB,UAAA,EAAY,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACzB,CAAC;AAMM,SAAS,uBACd,KAAA,EACwB;AAGxB,EAAA,OAAO;AAAA,IACL,cAAc,KAAA,CAAM,YAAA;AAAA,IACpB,eAAe,KAAA,CAAM,aAAA;AAAA,IACrB,eAAA,EAAiB,MAAM,eAAA,IAAmB,EAAA;AAAA,IAC1C,cAAc,KAAA,CAAM,YAAA;AAAA,IACpB,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,YAAY,KAAA,CAAM,UAAA;AAAA,IAClB,UAAA,EAAY,MAAM,UAAA,IAAc,EAAA;AAAA,IAChC,WAAA,EAAa,MAAM,WAAA,IAAe,EAAA;AAAA,IAClC,OAAO,KAAA,CAAM,KAAA;AAAA,IACb,SAAS,KAAA,CAAM,OAAA;AAAA,IACf,UAAA,EAAY,MAAM,UAAA,IAAc;AAAA,GAClC;AACF;;;AC5DO,IAAM,0BAAA,GAA6B;AAEnC,IAAM,4BAAA,GACX;;;ACLK,IAAM,0BAAA,GAA6B;AAEnC,IAAM,4BAAA,GACX;;;ACHK,IAAM,0BAAA,GAA6B;AAEnC,IAAM,4BAAA,GACX","file":"index.mjs","sourcesContent":["/**\n * Renderer wrapper for the `governance.signing-portal` canvakit template.\n *\n * The template is a self-contained HTML page that presents a `typed_name`\n * signing form. The host application is responsible for:\n * 1. Resolving the artifact + computing its SHA-256 documentHash.\n * 2. Generating a one-time nonce + signing URL.\n * 3. Receiving the form POST + writing the signature.json via\n * @agentproto/governance `signArtifact` runtime helper.\n *\n * This module does NOT call canvakit directly — it just exposes the template\n * id, the variable schema, and a builder helper. Apps wire it to their canvakit\n * renderer (e.g., @canvakit/core).\n */\n\nimport { z } from \"zod\"\n\nexport const SIGNING_PORTAL_TEMPLATE_ID = \"governance.signing-portal\" as const\n\n/** Path to the bundled .canvakit.html template (relative to the package root). */\nexport const SIGNING_PORTAL_TEMPLATE_PATH =\n \"src/spec/canvakit-templates/governance.signing-portal/template.canvakit.html\" as const\n\nexport const signingPortalVariablesSchema = z.object({\n /** Workspace-relative path to the artifact being signed. */\n artifactPath: z.string().min(1),\n /** Human-readable title to display (e.g., agreement title). */\n artifactTitle: z.string().min(1),\n /** Optional short excerpt of the artifact body (rendered above the form). */\n artifactExcerpt: z.string().optional(),\n /** SHA-256 hex of the artifact bytes; same value gets stored in signature.json. */\n documentHash: z.string().regex(/^[a-f0-9]{64}$/),\n /** Canonical signer kind (operator, user, counterparty, agent, external). */\n signerKind: z.enum([\"operator\", \"user\", \"counterparty\", \"agent\", \"external\"]),\n /** Canonical signer slug (without the `<kind>:` prefix). */\n signerSlug: z.string().min(1),\n /** Pre-filled name (if known); leave blank for a fresh portal session. */\n signerName: z.string().optional(),\n signerEmail: z.email().optional(),\n /** One-shot nonce token; signing endpoint MUST validate + invalidate on submit. */\n nonce: z.string().min(1),\n /** URL the form POSTs to. The endpoint receives a form-encoded body. */\n signUrl: z.string().min(1),\n /** Optional agency / company name shown in the lead paragraph. */\n agencyName: z.string().optional(),\n})\nexport type SigningPortalVariables = z.infer<\n typeof signingPortalVariablesSchema\n>\n\n/** Build the variable bag for the canvakit template, applying defaults for absent fields. */\nexport function signingPortalVariables(\n input: SigningPortalVariables\n): Record<string, string> {\n // canvakit's mustache engine treats undefined / \"\" identically for falsy\n // sections; we coerce optional fields to \"\".\n return {\n artifactPath: input.artifactPath,\n artifactTitle: input.artifactTitle,\n artifactExcerpt: input.artifactExcerpt ?? \"\",\n documentHash: input.documentHash,\n signerKind: input.signerKind,\n signerSlug: input.signerSlug,\n signerName: input.signerName ?? \"\",\n signerEmail: input.signerEmail ?? \"\",\n nonce: input.nonce,\n signUrl: input.signUrl,\n agencyName: input.agencyName ?? \"\",\n }\n}\n","/**\n * Renderer wrapper for the `governance.signature-card` canvakit template.\n *\n * Stub — Phase 4. Will display a single signature event as a compact card\n * (signer, method, timestamp, document hash truncated, evidence summary).\n *\n * For now, callers MAY render their own UI directly from a Signature object.\n */\n\nexport const SIGNATURE_CARD_TEMPLATE_ID = \"governance.signature-card\" as const\n\nexport const SIGNATURE_CARD_TEMPLATE_PATH =\n \"src/spec/canvakit-templates/governance.signature-card/template.canvakit.html\" as const\n\n// TODO(phase-4): implement template + variables schema.\n","/**\n * Renderer wrapper for the `governance.audit-timeline` canvakit template.\n *\n * Stub — Phase 4. Will display an audit-log.jsonl as a vertical timeline\n * (chronological, color-coded by action verb, with hash-chain integrity badge).\n */\n\nexport const AUDIT_TIMELINE_TEMPLATE_ID = \"governance.audit-timeline\" as const\n\nexport const AUDIT_TIMELINE_TEMPLATE_PATH =\n \"src/spec/canvakit-templates/governance.audit-timeline/template.canvakit.html\" as const\n\n// TODO(phase-4): implement template + variables schema.\n","/**\n * Renderer wrapper for the `governance.policy-summary` canvakit template.\n *\n * Stub — Phase 4. Will render a POLICY.md as a human-readable summary\n * (caps, threshold, required signers, escalation chain).\n */\n\nexport const POLICY_SUMMARY_TEMPLATE_ID = \"governance.policy-summary\" as const\n\nexport const POLICY_SUMMARY_TEMPLATE_PATH =\n \"src/spec/canvakit-templates/governance.policy-summary/template.canvakit.html\" as const\n\n// TODO(phase-4): implement template + variables schema.\n"]}
@@ -0,0 +1,61 @@
1
+ import { AuditEvent, Signature } from '../doctypes/index.js';
2
+ import { a as Policy } from '../policy-YqpSg3Ep.js';
3
+ import { V as VerifyChainOptions, a as VerifyChainResult } from '../verify-e_UfVr02.js';
4
+ import 'zod';
5
+
6
+ /**
7
+ * agentgovernance/v1 validators.
8
+ *
9
+ * Per-doctype validators that take file content (string) and return a typed
10
+ * ValidationResult. Cross-doctype consistency checks live alongside.
11
+ *
12
+ * Validators do NOT touch the filesystem — callers pass file contents in.
13
+ * For FS-aware orchestration, see `../../runtime/`.
14
+ */
15
+
16
+ type ValidationResult<T = unknown> = {
17
+ ok: true;
18
+ value: T;
19
+ warnings: string[];
20
+ } | {
21
+ ok: false;
22
+ errors: ValidationError[];
23
+ warnings: string[];
24
+ };
25
+ interface ValidationError {
26
+ path: string[];
27
+ message: string;
28
+ code?: string;
29
+ }
30
+ /**
31
+ * Validate a `signature.json` file content (raw JSON string).
32
+ */
33
+ declare function validateSignature(json: string): ValidationResult<Signature>;
34
+ /**
35
+ * Validate a single line of an audit-log.jsonl file.
36
+ *
37
+ * Whitespace is trimmed; empty input returns parse_error.
38
+ */
39
+ declare function validateAuditEvent(line: string): ValidationResult<AuditEvent>;
40
+ /**
41
+ * Validate a POLICY.md file content (markdown with YAML frontmatter).
42
+ */
43
+ declare function validatePolicy(markdown: string): ValidationResult<Policy>;
44
+ /**
45
+ * Validate an entire audit-log.jsonl file: every line parses + every line
46
+ * passes the audit-event schema + the hash chain verifies end-to-end.
47
+ *
48
+ * Returns the parsed events on success; the first mismatch (schema or chain)
49
+ * on failure.
50
+ */
51
+ declare function validateAuditLog(jsonl: string, opts: VerifyChainOptions): ValidationResult<{
52
+ events: AuditEvent[];
53
+ chain: VerifyChainResult;
54
+ }>;
55
+ /**
56
+ * Verify that a signature's `documentHash` matches the SHA-256 of the artifact bytes
57
+ * it claims to sign.
58
+ */
59
+ declare function validateSignatureAgainstArtifact(signature: Signature, artifactBytes: Uint8Array, computeSha256Hex: (bytes: Uint8Array) => string): ValidationResult<true>;
60
+
61
+ export { AuditEvent, Policy, Signature, type ValidationError, type ValidationResult, validateAuditEvent, validateAuditLog, validatePolicy, validateSignature, validateSignatureAgainstArtifact };
@@ -0,0 +1,5 @@
1
+ export { validateAuditEvent, validateAuditLog, validatePolicy, validateSignature, validateSignatureAgainstArtifact } from '../chunk-UVBFLWSG.mjs';
2
+ import '../chunk-VWEBMWO2.mjs';
3
+ import '../chunk-J2DX2WOA.mjs';
4
+ //# sourceMappingURL=index.mjs.map
5
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * agentgovernance/v1 hash-chain — verifier.
3
+ *
4
+ * Walks an audit-log.jsonl file, recomputing each line's signature given the
5
+ * previous one, and reports the first mismatch. Reports either:
6
+ * - ok with the count of verified lines + last signature (handy for anchoring)
7
+ * - first-mismatch diagnostic (line index, expected vs actual)
8
+ *
9
+ * The verifier is intentionally simple so third-party implementations in any
10
+ * language can be tested for compatibility. See `protocol.md` for the wire
11
+ * format and reference test vectors.
12
+ */
13
+ interface VerifyChainOptions {
14
+ /** HMAC secret (must match the one used to compute signatures). */
15
+ secret: string;
16
+ /** Workspace genesis seed (hex). Becomes prev_signature for the first line. */
17
+ genesisSeed: string;
18
+ /** Optional inclusive starting line index (0-based). Defaults to 0. */
19
+ rangeStart?: number;
20
+ /** Optional inclusive ending line index (0-based). Defaults to last line. */
21
+ rangeEnd?: number;
22
+ }
23
+ type VerifyChainResult = {
24
+ ok: true;
25
+ /** Number of lines verified (inside the optional range). */
26
+ verifiedLines: number;
27
+ /** The last line's signature — anchor candidate. */
28
+ lastSignature: string;
29
+ } | {
30
+ ok: false;
31
+ /** 0-based line index where verification failed. */
32
+ brokenAtLine: number;
33
+ /** What the verifier computed (expected). */
34
+ expected: string;
35
+ /** What the file claims (actual). */
36
+ actual: string;
37
+ /** Human-readable diagnostic. */
38
+ message: string;
39
+ /** Detail kind for programmatic handling. */
40
+ reason: "prev_signature_mismatch" | "signature_mismatch" | "missing_field" | "parse_error";
41
+ };
42
+ /**
43
+ * Verify a JSONL audit log's hash chain.
44
+ *
45
+ * Empty lines are skipped. Whitespace-only lines are skipped. JSON parse errors
46
+ * are reported as `parse_error`.
47
+ */
48
+ declare function verifyChain(jsonl: string, opts: VerifyChainOptions): VerifyChainResult;
49
+
50
+ export { type VerifyChainOptions as V, type VerifyChainResult as a, verifyChain as v };
package/package.json ADDED
@@ -0,0 +1,97 @@
1
+ {
2
+ "name": "@agentproto/governance",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "agentgovernance/v1 — universal contractual approval framework. Doctypes (signature.json, audit-log.jsonl, POLICY.md) describe how to record signatures, append hash-chained audit events, and declare autonomy policies as workspace files. Vendor-neutral, filesystem-first, third-party verifiable.",
5
+ "keywords": [
6
+ "agentgovernance",
7
+ "governance",
8
+ "approval",
9
+ "signature",
10
+ "audit-log",
11
+ "hash-chain",
12
+ "policy",
13
+ "open-standard",
14
+ "agentcompanies",
15
+ "agentic"
16
+ ],
17
+ "homepage": "https://agentproto.sh/docs/gov-1",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/agentproto/ts",
21
+ "directory": "packages/governance/core"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/agentproto/ts/issues"
25
+ },
26
+ "license": "MIT",
27
+ "type": "module",
28
+ "main": "dist/index.mjs",
29
+ "module": "dist/index.mjs",
30
+ "types": "dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.mjs",
35
+ "default": "./dist/index.mjs"
36
+ },
37
+ "./doctypes": {
38
+ "types": "./dist/doctypes/index.d.ts",
39
+ "import": "./dist/doctypes/index.mjs",
40
+ "default": "./dist/doctypes/index.mjs"
41
+ },
42
+ "./hash-chain": {
43
+ "types": "./dist/hash-chain/index.d.ts",
44
+ "import": "./dist/hash-chain/index.mjs",
45
+ "default": "./dist/hash-chain/index.mjs"
46
+ },
47
+ "./validators": {
48
+ "types": "./dist/validators/index.d.ts",
49
+ "import": "./dist/validators/index.mjs",
50
+ "default": "./dist/validators/index.mjs"
51
+ },
52
+ "./policy": {
53
+ "types": "./dist/policy/index.d.ts",
54
+ "import": "./dist/policy/index.mjs",
55
+ "default": "./dist/policy/index.mjs"
56
+ },
57
+ "./renderers": {
58
+ "types": "./dist/renderers/index.d.ts",
59
+ "import": "./dist/renderers/index.mjs",
60
+ "default": "./dist/renderers/index.mjs"
61
+ },
62
+ "./package.json": "./package.json",
63
+ "./AGENTGOVERNANCE.md": "./AGENTGOVERNANCE.md"
64
+ },
65
+ "files": [
66
+ "dist",
67
+ "src/spec/canvakit-templates",
68
+ "src/spec/agentgovernance-v1.md",
69
+ "AGENTGOVERNANCE.md",
70
+ "README.md",
71
+ "LICENSE"
72
+ ],
73
+ "publishConfig": {
74
+ "access": "public"
75
+ },
76
+ "dependencies": {
77
+ "gray-matter": "^4.0.3",
78
+ "yaml": "^2.8.4",
79
+ "zod": "^4.4.3",
80
+ "@agentproto/define-doctype": "0.1.0"
81
+ },
82
+ "devDependencies": {
83
+ "@types/node": "^25.6.2",
84
+ "tsup": "^8.5.1",
85
+ "typescript": "^5.9.3",
86
+ "vitest": "^3.2.4",
87
+ "@agentproto/tooling": "0.1.0-alpha.0"
88
+ },
89
+ "scripts": {
90
+ "dev": "tsup --watch",
91
+ "build": "tsup",
92
+ "clean": "rm -rf dist",
93
+ "check-types": "tsc --noEmit",
94
+ "test": "vitest run",
95
+ "test:watch": "vitest"
96
+ }
97
+ }
@@ -0,0 +1,100 @@
1
+ ---
2
+ template: true
3
+ name: governance.signing-portal
4
+ version: 1.0.0-alpha
5
+ description: |
6
+ Single-page signing portal for `typed_name` signatures on agentgovernance/v1 artifacts.
7
+ Renders a form where the signer types their full name and submits. The host application
8
+ is responsible for posting the form, capturing IP/UA evidence, and writing the
9
+ signature.json file via @agentproto/governance-engine.
10
+ author: governance.sh
11
+ variables:
12
+ artifactPath: "engagements/example/AGREEMENT.md"
13
+ artifactTitle: "Agreement"
14
+ artifactExcerpt: ""
15
+ documentHash: "0000000000000000000000000000000000000000000000000000000000000000"
16
+ signerKind: "counterparty"
17
+ signerSlug: "example-corp"
18
+ signerName: ""
19
+ signerEmail: ""
20
+ nonce: ""
21
+ signUrl: "/api/governance/sign"
22
+ agencyName: ""
23
+ sources: {}
24
+ ---
25
+ <!doctype html>
26
+ <html lang="en">
27
+ <head>
28
+ <meta charset="utf-8" />
29
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
30
+ <title>Sign: {{artifactTitle}}</title>
31
+ <style>
32
+ :root {
33
+ --fg: #1a1a1a;
34
+ --muted: #666;
35
+ --bg: #faf9f7;
36
+ --panel: #ffffff;
37
+ --border: #e5e5e5;
38
+ --accent: #1a1a1a;
39
+ }
40
+ body { font: 16px/1.5 ui-sans-serif, system-ui, -apple-system, sans-serif; max-width: 36rem; margin: 0 auto; padding: 3rem 1.5rem; color: var(--fg); background: var(--bg); }
41
+ h1 { font-size: 1.5rem; letter-spacing: -0.01em; margin: 0 0 0.5rem; }
42
+ .lead { color: var(--muted); margin: 0 0 2rem; }
43
+ .panel { background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; margin-bottom: 1.5rem; }
44
+ .field { margin-bottom: 1rem; }
45
+ label { display: block; font-size: 0.875rem; font-weight: 500; margin-bottom: 0.375rem; color: #333; }
46
+ input { width: 100%; padding: 0.625rem 0.75rem; border: 1px solid #d4d4d4; border-radius: 6px; font: inherit; box-sizing: border-box; background: #fff; color: var(--fg); }
47
+ input:focus { outline: 2px solid #2563eb; outline-offset: -2px; }
48
+ .meta { font-size: 0.875rem; color: var(--muted); padding: 0.875rem 1rem; background: #f5f4f0; border: 1px solid var(--border); border-radius: 6px; margin-bottom: 1rem; }
49
+ .meta dl { margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: 0.25rem 0.75rem; }
50
+ .meta dt { font-weight: 500; color: #333; }
51
+ .meta dd { margin: 0; font-family: ui-monospace, SF Mono, monospace; font-size: 0.8125rem; word-break: break-all; }
52
+ button { width: 100%; padding: 0.75rem 1rem; background: var(--accent); color: white; border: 0; border-radius: 6px; font: inherit; font-weight: 500; cursor: pointer; transition: background 0.1s; }
53
+ button:hover { background: #000; }
54
+ button:disabled { background: #999; cursor: not-allowed; }
55
+ .legal { font-size: 0.8125rem; color: #777; margin-top: 1.5rem; line-height: 1.6; }
56
+ .legal em { font-style: normal; font-weight: 500; color: var(--fg); }
57
+ .excerpt { background: #fafafa; border: 1px solid var(--border); border-radius: 6px; padding: 1rem; margin: 0 0 1rem; max-height: 14rem; overflow: auto; font-size: 0.875rem; line-height: 1.55; white-space: pre-wrap; }
58
+ .agency { font-size: 0.875rem; color: var(--muted); margin-bottom: 1.5rem; }
59
+ </style>
60
+ </head>
61
+ <body>
62
+ <h1>Sign &ldquo;{{artifactTitle}}&rdquo;</h1>
63
+ <p class="lead">
64
+ You are signing on behalf of <strong>{{signerKind}}:{{signerSlug}}</strong>{{#agencyName}} for {{agencyName}}{{/agencyName}}.
65
+ </p>
66
+
67
+ {{#artifactExcerpt}}
68
+ <div class="excerpt">{{artifactExcerpt}}</div>
69
+ {{/artifactExcerpt}}
70
+
71
+ <div class="panel">
72
+ <form id="signing-form" action="{{signUrl}}" method="POST">
73
+ <input type="hidden" name="nonce" value="{{nonce}}" />
74
+ <input type="hidden" name="artifactPath" value="{{artifactPath}}" />
75
+ <input type="hidden" name="documentHash" value="{{documentHash}}" />
76
+ <input type="hidden" name="signer" value="{{signerKind}}:{{signerSlug}}" />
77
+ <input type="hidden" name="signerKind" value="{{signerKind}}" />
78
+ {{#signerEmail}}<input type="hidden" name="signerEmail" value="{{signerEmail}}" />{{/signerEmail}}
79
+
80
+ <div class="field">
81
+ <label for="signerName">Type your full legal name to sign</label>
82
+ <input id="signerName" name="signerName" type="text" required value="{{signerName}}" autocomplete="name" />
83
+ </div>
84
+
85
+ <button type="submit">Sign &amp; submit</button>
86
+ </form>
87
+ </div>
88
+
89
+ <div class="meta">
90
+ <dl>
91
+ <dt>Artifact</dt><dd>{{artifactPath}}</dd>
92
+ <dt>SHA-256</dt><dd>{{documentHash}}</dd>
93
+ </dl>
94
+ </div>
95
+
96
+ <p class="legal">
97
+ By typing your name and clicking <em>Sign &amp; submit</em>, you create a binding electronic signature. The host application captures your typed name, IP address, browser user agent, and a one-time nonce as evidence. The artifact&rsquo;s content is identified by its SHA-256 hash above; if the hash changes, this signature does not apply.
98
+ </p>
99
+ </body>
100
+ </html>