@halofy/agent-connect 0.13.1 → 0.13.2

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/README.md CHANGED
@@ -311,6 +311,17 @@ updated disposable installation. Existing local runtimes do not auto-upgrade.
311
311
 
312
312
  ## Organization instructions (0.10.0)
313
313
 
314
+ The 0.13.2 release candidate includes an MCP policy validator extension.
315
+ It accepts one final generated `Required MCP access policy` document in the
316
+ connection's exact namespace, alongside ordinary authored instructions. That
317
+ document may exceed 16 KiB; the complete instruction bundle still cannot exceed
318
+ 64 KiB. Ordinary documents keep their 16 KiB limit and unique, ordered ancestor
319
+ scopes. Content hashes, bundle digest, UTF-8 and managed-marker checks still apply.
320
+ Existing installed `0.13.1` runtimes without this extension reject same-scope
321
+ authored/generated pairs and generated policies above 16 KiB. They need an
322
+ upgraded runtime; this source change neither publishes a package nor upgrades
323
+ existing installations. Invalid bundles leave existing local files untouched.
324
+
314
325
  This source adds Govern instruction delivery alongside the existing skill,
315
326
  policy, knowledge and delivery-receipt paths. Activation requires the reviewed
316
327
  0.10.0 npm publication, matching server deployment and a fresh confirmed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@halofy/agent-connect",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "type": "module",
5
5
  "description": "Halofy lifecycle installer and runtime for supported agents; runtime requests are signed with a per-installation Ed25519 key",
6
6
  "bin": {
@@ -12,6 +12,7 @@ export const INSTALL_INSTRUCTION_SYNC_TIMEOUT_MS = 15_000;
12
12
 
13
13
  const sha = (value) => createHash("sha256").update(value).digest("hex");
14
14
  const HEX = /^[a-f0-9]{64}$/;
15
+ const MCP_POLICY_ID = /^mcp-policy-[a-f0-9]{64}$/;
15
16
  const MARKER = "<!-- HALOFY-INSTRUCTIONS:";
16
17
  const fail = (code) => { throw Object.assign(new Error(code), { instructionCode: code }); };
17
18
  const plain = (value) => value && typeof value === "object" && !Array.isArray(value);
@@ -34,16 +35,21 @@ export function validateInstructionBundle(bundle, expectedNamespace) {
34
35
  bundle.namespace !== expectedNamespace || !HEX.test(bundle.digest) || !Array.isArray(bundle.documents) ||
35
36
  Buffer.byteLength(JSON.stringify(bundle)) > 64 * 1024) fail("invalid_bundle");
36
37
  let previous = null;
37
- const documents = bundle.documents.map((doc) => {
38
+ const documents = bundle.documents.map((doc, index) => {
39
+ // This reserved identifier is a wire discriminator, not an authenticity
40
+ // proof. Authority still comes from the authorized server response.
41
+ const generatedPolicy = plain(doc) && typeof doc.id === "string" && MCP_POLICY_ID.test(doc.id);
38
42
  if (!plain(doc) || typeof doc.id !== "string" || !/^[A-Za-z0-9_-]{1,160}$/.test(doc.id) || !scope(doc.namespace) ||
39
43
  !(doc.namespace === "" || doc.namespace === expectedNamespace || expectedNamespace.startsWith(`${doc.namespace}/`)) ||
40
- (previous !== null && !(doc.namespace !== previous && (previous === "" || doc.namespace.startsWith(`${previous}/`)))) ||
44
+ (doc.id.startsWith("mcp-policy-") && !generatedPolicy) ||
45
+ (generatedPolicy && (index !== bundle.documents.length - 1 || doc.namespace !== expectedNamespace || doc.title !== "Required MCP access policy")) ||
46
+ (!generatedPolicy && previous !== null && !(doc.namespace !== previous && (previous === "" || doc.namespace.startsWith(`${previous}/`)))) ||
41
47
  !Number.isSafeInteger(doc.version) || doc.version < 1 || typeof doc.title !== "string" || !doc.title.trim() || doc.title.length > 160 || doc.title.includes(MARKER) ||
42
48
  /[\u0000-\u001f\u007f]/.test(doc.title) || typeof doc.content !== "string" || !doc.content.trim() ||
43
49
  Buffer.from(doc.title, "utf8").toString("utf8") !== doc.title || Buffer.from(doc.content, "utf8").toString("utf8") !== doc.content ||
44
- doc.content.includes("\0") || doc.content.includes(MARKER) || Buffer.byteLength(doc.content) > 16 * 1024 ||
50
+ doc.content.includes("\0") || doc.content.includes(MARKER) || Buffer.byteLength(doc.content) > (generatedPolicy ? 64 : 16) * 1024 ||
45
51
  !HEX.test(doc.sha256) || sha(doc.content) !== doc.sha256) fail("invalid_bundle");
46
- previous = doc.namespace;
52
+ if (!generatedPolicy) previous = doc.namespace;
47
53
  return { id: doc.id, namespace: doc.namespace, version: doc.version, title: doc.title, content: doc.content, sha256: doc.sha256 };
48
54
  });
49
55
  if (sha(JSON.stringify(documents)) !== bundle.digest) fail("invalid_bundle");
package/src/version.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  export const PACKAGE_NAME = "@halofy/agent-connect";
2
- export const INSTALLER_VERSION = "0.13.1";
3
- export const RUNTIME_VERSION = "0.13.1";
2
+ export const INSTALLER_VERSION = "0.13.2";
3
+ export const RUNTIME_VERSION = "0.13.2";
4
4
  export const DISCLOSURE_VERSION = "halofy-agent-lifecycle-2026-09-17.1";