youmd 0.13.6 → 0.13.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "youmd",
3
- "version": "0.13.6",
3
+ "version": "0.13.7",
4
4
  "description": "Identity context protocol for the agent internet — an MCP where the context is you. CLI for the You.md platform.",
5
5
  "bin": {
6
6
  "you": "dist/you.js",
@@ -13,13 +13,12 @@ const jsonFile = path.resolve(jsonPath);
13
13
  function repositoryRoot(start) {
14
14
  let current = fs.realpathSync(start);
15
15
  for (let depth = 0; depth < 12; depth += 1) {
16
- const schema = path.join(current, "contracts/project-brain/vision-artifacts.schema.json");
17
- if (fs.existsSync(schema) && fs.lstatSync(schema).isFile()) return current;
16
+ if (fs.existsSync(path.join(current, ".git"))) return current;
18
17
  const parent = path.dirname(current);
19
18
  if (parent === current) break;
20
19
  current = parent;
21
20
  }
22
- throw new Error("could not find repository Vision Artifact schema from manifest path");
21
+ throw new Error("could not find a Git repository from manifest path");
23
22
  }
24
23
  function safeRepositoryFile(root, relative) {
25
24
  if (typeof relative !== "string" || relative.includes("\\") || path.isAbsolute(relative)
@@ -33,7 +32,11 @@ function safeRepositoryFile(root, relative) {
33
32
  }
34
33
  const root = repositoryRoot(path.dirname(jsonFile));
35
34
  const manifest = JSON.parse(fs.readFileSync(jsonFile, "utf8"));
36
- const schema = JSON.parse(fs.readFileSync(path.join(root, "contracts/project-brain/vision-artifacts.schema.json"), "utf8"));
35
+ const repositorySchema = path.join(root, "contracts/project-brain/vision-artifacts.schema.json");
36
+ const packagedSchema = path.resolve(import.meta.dirname, "../skills/templates/living-vision-artifact/vision-artifacts.schema.json");
37
+ const schemaPath = fs.existsSync(repositorySchema) ? repositorySchema : packagedSchema;
38
+ if (!fs.existsSync(schemaPath)) throw new Error("Vision Artifact schema is unavailable in both the repository and installed You.md runtime");
39
+ const schema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
37
40
  const ajv = new Ajv2020({ allErrors: true, strict: true });
38
41
  addFormats(ajv);
39
42
  const validate = ajv.compile(schema);
@@ -7,6 +7,11 @@ import test from "node:test";
7
7
 
8
8
  const repo = path.resolve(import.meta.dirname, "../..");
9
9
  const validator = path.join(repo, "cli/scripts/validate-living-vision-artifact.mjs");
10
+ test("keeps the packaged validator schema identical to the canonical contract", () => {
11
+ const canonical = JSON.parse(fs.readFileSync(path.join(repo, "contracts/project-brain/vision-artifacts.schema.json"), "utf8"));
12
+ const packaged = JSON.parse(fs.readFileSync(path.join(repo, "cli/skills/templates/living-vision-artifact/vision-artifacts.schema.json"), "utf8"));
13
+ assert.deepEqual(packaged, canonical);
14
+ });
10
15
  function makeRepo() {
11
16
  const root = fs.mkdtempSync(path.join(os.tmpdir(), "vision-artifact-"));
12
17
  fs.mkdirSync(path.join(root, "contracts/project-brain"), { recursive: true });
@@ -31,4 +36,5 @@ function manifest(sha, status = "proposed") { return {
31
36
  function writeValid(root, sha) { const value = manifest(sha); fs.writeFileSync(path.join(root, "project-context/source.md"), "source\n"); fs.writeFileSync(path.join(root, "project-context/VISION.md"), `# Vision\n\n**Candidate revision:** \`git:${sha}\`\n`); fs.writeFileSync(path.join(root, "project-context/VISION.html"), `<p>git:${sha}</p>`); fs.writeFileSync(path.join(root, "project-context/VISION_ARTIFACTS.json"), JSON.stringify(value)); return value; }
32
37
  function run(root) { try { return execFileSync("node", [validator, "project-context/VISION_ARTIFACTS.json"], { cwd: root, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }); } catch (error) { throw new Error(String(error.stderr || error.message)); } }
33
38
  test("validates a nested project-context manifest from its repository root", () => { const { root, sha } = makeRepo(); try { writeValid(root, sha); assert.match(run(root), /validated 1/); } finally { fs.rmSync(root, { recursive: true, force: true }); } });
39
+ test("uses the packaged schema in an arbitrary Git project", () => { const { root, sha } = makeRepo(); try { writeValid(root, sha); fs.rmSync(path.join(root, "contracts"), { recursive: true, force: true }); assert.match(run(root), /validated 1/); } finally { fs.rmSync(root, { recursive: true, force: true }); } });
34
40
  test("rejects traversal, missing projections, and unaccepted acceptance receipts", () => { const { root, sha } = makeRepo(); try { const value = writeValid(root, sha); value.artifacts[0].formats.markdown = "../escape.md"; fs.writeFileSync(path.join(root, "project-context/VISION_ARTIFACTS.json"), JSON.stringify(value)); assert.throws(() => run(root), /invalid Vision Artifact JSON/); value.artifacts[0].formats.markdown = "project-context/missing.md"; fs.writeFileSync(path.join(root, "project-context/VISION_ARTIFACTS.json"), JSON.stringify(value)); assert.throws(() => run(root), /missing artifact projection/); value.artifacts[0].formats.markdown = "project-context/VISION.md"; value.artifacts[0].lineage.acceptanceRef = "review:fake"; fs.writeFileSync(path.join(root, "project-context/VISION_ARTIFACTS.json"), JSON.stringify(value)); assert.throws(() => run(root), /must not pre-populate acceptanceRef/); } finally { fs.rmSync(root, { recursive: true, force: true }); } });
@@ -23,7 +23,7 @@ Use this You.md-owned skill for a project vision, strategy, roadmap, audit, plan
23
23
  3. Copy the three files in `cli/skills/templates/living-vision-artifact/` using one shared stem, e.g. `PROJECT_STRATEGY_2026-08-13.{md,json,html}`. Fill every placeholder from evidence only.
24
24
  4. In the JSON manifest, keep all four horizons and every lane explicit. Give the artifact `status: "proposed"`, `trustDomain`, paths for all three formats, exact provenance paths, a new monotonically increasing version, and lineage with the prior version id. `acceptanceRef` stays absent until human acceptance.
25
25
  5. Render the branded HTML from the Markdown/JSON facts: include the artifact id, candidate Git revision, status, horizon, lane ids, provenance, and review date in the visible metadata. Block scripts and external embeds.
26
- 6. Validate with `node cli/scripts/validate-living-vision-artifact.mjs project-context/VISION_ARTIFACTS.json`; it checks the contract schema, exact three-format paths, candidate revision bindings, no-script HTML, and acceptance discipline. Then verify every claimed Git ref resolves locally. Run `npm run project-brain:contract-check` as the broader Project Brain gate.
26
+ 6. Validate with the repository script when present: `node cli/scripts/validate-living-vision-artifact.mjs project-context/VISION_ARTIFACTS.json`. In another project, use the installed runtime: `node ~/.you/npm-current/lib/node_modules/youmd/scripts/validate-living-vision-artifact.mjs project-context/VISION_ARTIFACTS.json`. It carries the contract schema and checks exact three-format paths, candidate revision bindings, no-script HTML, and acceptance discipline. Then verify every claimed Git ref resolves locally. In the You.md source repo, also run `npm run project-brain:contract-check`.
27
27
  7. Present the candidate and exact Git revision for human review. Only after a human supplies an attributable receipt may a separate proposal change it to `accepted` and set `lineage.acceptanceRef` to an immutable receipt/ref.
28
28
 
29
29
  ## Required Markdown sections
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://you.md/schemas/project-vision-artifacts/v1",
4
+ "title": "You.md Project Vision Artifacts Index",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["$schema", "schemaVersion", "kind", "projectRef", "northStar", "positioning", "horizons", "lanes", "artifacts", "updatedAt"],
8
+ "properties": {
9
+ "$schema": { "const": "https://you.md/schemas/project-vision-artifacts/v1" },
10
+ "schemaVersion": { "const": "you-md/project-vision-artifacts/v1" },
11
+ "kind": { "const": "project-vision-artifacts" },
12
+ "projectRef": { "$ref": "#/$defs/projectRef" },
13
+ "northStar": { "type": "object", "additionalProperties": false, "required": ["statement", "invariants", "evidenceRefs"], "properties": {
14
+ "statement": { "type": "string", "minLength": 1, "maxLength": 1200 },
15
+ "invariants": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 1200 } },
16
+ "evidenceRefs": { "type": "array", "minItems": 1, "maxItems": 64, "uniqueItems": true, "items": { "$ref": "#/$defs/relativePath" } }
17
+ } },
18
+ "positioning": { "type": "object", "additionalProperties": false, "required": ["youmd", "bamfAi", "bamfOs"], "properties": {
19
+ "youmd": { "type": "string", "minLength": 1, "maxLength": 1200 },
20
+ "bamfAi": { "type": "string", "minLength": 1, "maxLength": 1200 },
21
+ "bamfOs": { "type": "string", "minLength": 1, "maxLength": 1200 }
22
+ } },
23
+ "horizons": { "type": "object", "additionalProperties": false, "required": ["year", "quarter", "month", "week"], "properties": {
24
+ "year": { "$ref": "#/$defs/horizon" }, "quarter": { "$ref": "#/$defs/horizon" }, "month": { "$ref": "#/$defs/horizon" }, "week": { "$ref": "#/$defs/horizon" }
25
+ } },
26
+ "lanes": { "type": "array", "maxItems": 64, "items": { "type": "object", "additionalProperties": false, "required": ["id", "name", "kind", "ownerAgentRef", "scopeRefs", "claimMode", "status", "dependsOn", "reviewAt"], "properties": {
27
+ "id": { "$ref": "#/$defs/id" }, "name": { "type": "string", "minLength": 1, "maxLength": 160 },
28
+ "kind": { "enum": ["product", "implementation", "qa", "companion"] },
29
+ "ownerAgentRef": { "type": "string", "pattern": "^agent:[A-Za-z0-9][A-Za-z0-9._:/-]{0,190}$" },
30
+ "scopeRefs": { "type": "array", "minItems": 1, "maxItems": 64, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 220 } },
31
+ "claimMode": { "enum": ["evidence-only", "propose", "managed-write"] }, "status": { "enum": ["planned", "active", "blocked", "review", "done"] },
32
+ "dependsOn": { "type": "array", "maxItems": 32, "uniqueItems": true, "items": { "$ref": "#/$defs/id" } },
33
+ "lastReceiptRef": { "type": "string", "minLength": 1, "maxLength": 220 }, "reviewAt": { "type": "string", "format": "date-time" }
34
+ } } },
35
+ "artifacts": { "type": "array", "maxItems": 512, "items": { "type": "object", "additionalProperties": false, "required": ["id", "title", "family", "scopeRefs", "version", "status", "trustDomain", "createdAt", "reviewAt", "formats", "lineage", "provenance"], "properties": {
36
+ "id": { "$ref": "#/$defs/id" }, "title": { "type": "string", "minLength": 1, "maxLength": 240 },
37
+ "family": { "enum": ["vision", "north-star", "strategy", "planning", "audit", "operations"] },
38
+ "scopeRefs": { "type": "array", "minItems": 1, "maxItems": 64, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 220 } },
39
+ "horizon": { "enum": ["year", "quarter", "month", "week"] }, "version": { "type": "integer", "minimum": 1 },
40
+ "candidateRevision": { "type": "string", "pattern": "^git:[a-f0-9]{7,64}$" },
41
+ "status": { "enum": ["draft", "proposed", "accepted", "superseded"] }, "trustDomain": { "enum": ["owner-private", "project-private", "shared", "public"] },
42
+ "createdAt": { "type": "string", "format": "date-time" }, "reviewAt": { "type": "string", "format": "date-time" },
43
+ "formats": { "type": "object", "additionalProperties": false, "minProperties": 1, "properties": {
44
+ "markdown": { "$ref": "#/$defs/relativePath" }, "html": { "$ref": "#/$defs/relativePath" }, "json": { "$ref": "#/$defs/relativePath" }
45
+ } },
46
+ "lineage": { "type": "object", "additionalProperties": false, "required": ["relation", "parentVersionId", "main"], "properties": {
47
+ "relation": { "enum": ["main", "fork", "remix", "supersedes"] }, "parentVersionId": { "type": ["string", "null"], "maxLength": 220 },
48
+ "main": { "type": "boolean" }, "acceptanceRef": { "type": "string", "minLength": 1, "maxLength": 220 }
49
+ } },
50
+ "provenance": { "type": "array", "minItems": 1, "maxItems": 64, "uniqueItems": true, "items": { "$ref": "#/$defs/relativePath" } }
51
+ } } },
52
+ "updatedAt": { "type": "string", "format": "date-time" }
53
+ },
54
+ "$defs": {
55
+ "projectRef": { "type": "string", "pattern": "^project:[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$" },
56
+ "id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{0,127}$" },
57
+ "relativePath": { "type": "string", "minLength": 1, "maxLength": 500, "pattern": "^(?!/)(?![A-Za-z]:)(?!.*\\\\)(?!.*//)(?!.*(?:^|/)(?:\\.{1,2})(?:/|$))(?!.*[\\u0000-\\u001f\\u007f])(?!.*\\/$)[^/]+(?:/[^/]+)*$" },
58
+ "horizon": { "type": "object", "additionalProperties": false, "required": ["period", "objective", "outcomes", "focusRefs", "status", "reviewAt"], "properties": {
59
+ "period": { "type": "string", "minLength": 1, "maxLength": 40 }, "objective": { "type": "string", "minLength": 1, "maxLength": 1200 },
60
+ "outcomes": { "type": "array", "minItems": 1, "maxItems": 32, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 1200 } },
61
+ "focusRefs": { "type": "array", "maxItems": 64, "uniqueItems": true, "items": { "type": "string", "minLength": 1, "maxLength": 220 } },
62
+ "status": { "enum": ["planned", "active", "review", "done"] }, "reviewAt": { "type": "string", "format": "date-time" }
63
+ } }
64
+ }
65
+ }