youmd 0.13.5 → 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/native/prebuilds/darwin-universal/youmd_safe_open.node +0 -0
- package/package.json +2 -1
- package/scripts/validate-living-vision-artifact.mjs +59 -0
- package/scripts/validate-living-vision-artifact.test.mjs +40 -0
- package/skills/living-vision-artifact.md +35 -0
- package/skills/templates/living-vision-artifact/VISION_ARTIFACT.html +1 -0
- package/skills/templates/living-vision-artifact/VISION_ARTIFACT.json +17 -0
- package/skills/templates/living-vision-artifact/VISION_ARTIFACT.md +39 -0
- package/skills/templates/living-vision-artifact/vision-artifacts.schema.json +65 -0
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "youmd",
|
|
3
|
-
"version": "0.13.
|
|
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",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"test:brain-content": "vitest run src/__tests__/brain-content.test.ts src/__tests__/brain-safe-open-native.test.ts",
|
|
28
28
|
"pretest:brain-content:abi": "npm run build:native",
|
|
29
29
|
"test:brain-content:abi": "node scripts/smoke-safe-open-node.cjs",
|
|
30
|
+
"test:living-vision-artifact": "node --test scripts/validate-living-vision-artifact.test.mjs",
|
|
30
31
|
"test:watch": "vitest",
|
|
31
32
|
"prepack": "npm run build:native && npm run build",
|
|
32
33
|
"prepublishOnly": "node scripts/check-version-exists.mjs && npm run build:native && npm run build",
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { execFileSync } from "node:child_process";
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
const Ajv2020 = require("ajv/dist/2020").default;
|
|
9
|
+
const addFormats = require("ajv-formats").default;
|
|
10
|
+
const [jsonPath] = process.argv.slice(2);
|
|
11
|
+
if (!jsonPath) throw new Error("usage: validate-living-vision-artifact.mjs path/to/VISION_ARTIFACT.json");
|
|
12
|
+
const jsonFile = path.resolve(jsonPath);
|
|
13
|
+
function repositoryRoot(start) {
|
|
14
|
+
let current = fs.realpathSync(start);
|
|
15
|
+
for (let depth = 0; depth < 12; depth += 1) {
|
|
16
|
+
if (fs.existsSync(path.join(current, ".git"))) return current;
|
|
17
|
+
const parent = path.dirname(current);
|
|
18
|
+
if (parent === current) break;
|
|
19
|
+
current = parent;
|
|
20
|
+
}
|
|
21
|
+
throw new Error("could not find a Git repository from manifest path");
|
|
22
|
+
}
|
|
23
|
+
function safeRepositoryFile(root, relative) {
|
|
24
|
+
if (typeof relative !== "string" || relative.includes("\\") || path.isAbsolute(relative)
|
|
25
|
+
|| relative.split("/").includes("..")) throw new Error(`unsafe artifact path: ${relative}`);
|
|
26
|
+
const target = path.resolve(root, relative);
|
|
27
|
+
if (!target.startsWith(`${root}${path.sep}`)) throw new Error(`artifact path escapes repository: ${relative}`);
|
|
28
|
+
if (!fs.existsSync(target)) throw new Error(`missing artifact projection ${relative}`);
|
|
29
|
+
const real = fs.realpathSync(target);
|
|
30
|
+
if (!real.startsWith(`${root}${path.sep}`)) throw new Error(`artifact projection resolves outside repository: ${relative}`);
|
|
31
|
+
return real;
|
|
32
|
+
}
|
|
33
|
+
const root = repositoryRoot(path.dirname(jsonFile));
|
|
34
|
+
const manifest = JSON.parse(fs.readFileSync(jsonFile, "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"));
|
|
40
|
+
const ajv = new Ajv2020({ allErrors: true, strict: true });
|
|
41
|
+
addFormats(ajv);
|
|
42
|
+
const validate = ajv.compile(schema);
|
|
43
|
+
if (!validate(manifest)) throw new Error(`invalid Vision Artifact JSON: ${ajv.errorsText(validate.errors)}`);
|
|
44
|
+
for (const artifact of manifest.artifacts) {
|
|
45
|
+
if (!artifact.candidateRevision) throw new Error(`${artifact.id}: candidateRevision is required for a new Living Vision Artifact`);
|
|
46
|
+
if (artifact.status === "accepted" && !artifact.lineage.acceptanceRef) throw new Error(`${artifact.id}: accepted artifacts require an attributable acceptanceRef`);
|
|
47
|
+
if (artifact.status !== "accepted" && artifact.lineage.acceptanceRef) throw new Error(`${artifact.id}: agents must not pre-populate acceptanceRef`);
|
|
48
|
+
for (const [format, relative] of Object.entries(artifact.formats)) {
|
|
49
|
+
try { safeRepositoryFile(root, relative); }
|
|
50
|
+
catch (error) { throw new Error(`${artifact.id}: ${error.message}`); }
|
|
51
|
+
}
|
|
52
|
+
try { execFileSync("git", ["rev-parse", "--verify", `${artifact.candidateRevision.slice(4)}^{commit}`], { cwd: root, stdio: "ignore" }); }
|
|
53
|
+
catch { throw new Error(`${artifact.id}: candidateRevision does not resolve to a local Git commit`); }
|
|
54
|
+
const markdown = fs.readFileSync(safeRepositoryFile(root, artifact.formats.markdown), "utf8");
|
|
55
|
+
const html = fs.readFileSync(safeRepositoryFile(root, artifact.formats.html), "utf8");
|
|
56
|
+
if (!markdown.includes(`Candidate revision:** \`${artifact.candidateRevision}\``)) throw new Error(`${artifact.id}: Markdown is not bound to candidateRevision`);
|
|
57
|
+
if (/<script\b/i.test(html) || !html.includes(artifact.candidateRevision)) throw new Error(`${artifact.id}: HTML must be script-free and revision-bound`);
|
|
58
|
+
}
|
|
59
|
+
console.log(`validated ${manifest.artifacts.length} Living Vision Artifact(s)`);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
|
|
8
|
+
const repo = path.resolve(import.meta.dirname, "../..");
|
|
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
|
+
});
|
|
15
|
+
function makeRepo() {
|
|
16
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "vision-artifact-"));
|
|
17
|
+
fs.mkdirSync(path.join(root, "contracts/project-brain"), { recursive: true });
|
|
18
|
+
fs.mkdirSync(path.join(root, "project-context"));
|
|
19
|
+
fs.copyFileSync(path.join(repo, "contracts/project-brain/vision-artifacts.schema.json"), path.join(root, "contracts/project-brain/vision-artifacts.schema.json"));
|
|
20
|
+
execFileSync("git", ["init", "-q"], { cwd: root });
|
|
21
|
+
execFileSync("git", ["config", "user.email", "test@example.com"], { cwd: root });
|
|
22
|
+
execFileSync("git", ["config", "user.name", "Test"], { cwd: root });
|
|
23
|
+
fs.writeFileSync(path.join(root, "seed.txt"), "seed\n");
|
|
24
|
+
execFileSync("git", ["add", "."], { cwd: root }); execFileSync("git", ["commit", "-qm", "seed"], { cwd: root });
|
|
25
|
+
const sha = execFileSync("git", ["rev-parse", "HEAD"], { cwd: root, encoding: "utf8" }).trim();
|
|
26
|
+
return { root, sha };
|
|
27
|
+
}
|
|
28
|
+
function manifest(sha, status = "proposed") { return {
|
|
29
|
+
$schema: "https://you.md/schemas/project-vision-artifacts/v1", schemaVersion: "you-md/project-vision-artifacts/v1", kind: "project-vision-artifacts", projectRef: "project:fixture",
|
|
30
|
+
northStar: { statement: "North star", invariants: ["Invariant"], evidenceRefs: ["project-context/source.md"] },
|
|
31
|
+
positioning: { youmd: "You", bamfAi: "AI", bamfOs: "OS" },
|
|
32
|
+
horizons: Object.fromEntries(["year", "quarter", "month", "week"].map((key) => [key, { period: "2026", objective: "Objective", outcomes: ["Outcome"], focusRefs: ["project:fixture"], status: "planned", reviewAt: "2026-12-01T00:00:00.000Z" }])),
|
|
33
|
+
lanes: [{ id: "vision", name: "Vision", kind: "product", ownerAgentRef: "agent:fixture", scopeRefs: ["project:fixture"], claimMode: "propose", status: "planned", dependsOn: [], reviewAt: "2026-12-01T00:00:00.000Z" }],
|
|
34
|
+
artifacts: [{ id: "fixture-vision", title: "Fixture Vision", family: "vision", scopeRefs: ["project:fixture"], horizon: "week", version: 1, candidateRevision: `git:${sha}`, status, trustDomain: "owner-private", createdAt: "2026-08-13T00:00:00.000Z", reviewAt: "2026-08-20T00:00:00.000Z", formats: { markdown: "project-context/VISION.md", json: "project-context/VISION_ARTIFACTS.json", html: "project-context/VISION.html" }, lineage: { relation: "main", parentVersionId: null, main: true }, provenance: ["project-context/source.md"] }], updatedAt: "2026-08-13T00:00:00.000Z",
|
|
35
|
+
}; }
|
|
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; }
|
|
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)); } }
|
|
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 }); } });
|
|
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 }); } });
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: living-vision-artifact
|
|
3
|
+
version: 1.0.0
|
|
4
|
+
scope: project
|
|
5
|
+
description: "Create or propose a revision-bound Vision Artifact as Markdown, validated JSON, and branded HTML review projection"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# living-vision-artifact
|
|
9
|
+
|
|
10
|
+
Use this You.md-owned skill for a project vision, strategy, roadmap, audit, plan, report, or brief that requires a durable human-review object. It is not a general document-template skill: it binds to the Project Brain contract at `contracts/project-brain/vision-artifacts.schema.json`.
|
|
11
|
+
|
|
12
|
+
## Ownership and safety
|
|
13
|
+
|
|
14
|
+
- Write only under the declared `project-context/` root; never scan or ingest repository-wide HTML.
|
|
15
|
+
- Markdown is the authored, reviewable source. JSON is the manifest/index. HTML is a projection of the exact Markdown/JSON revision, never an independent authority.
|
|
16
|
+
- Do not replace an accepted human vision. Material changes create a new `version`, preserve the prior file, set lineage to `supersedes`/`fork`/`remix`, and remain `proposed` until an attributable human acceptance receipt exists.
|
|
17
|
+
- Never fabricate acceptance, evidence, metrics, Git revisions, lanes, or review dates. An agent may make a candidate only.
|
|
18
|
+
|
|
19
|
+
## Create or update
|
|
20
|
+
|
|
21
|
+
1. Read `project-context/VISION_ARTIFACTS.json`, the current accepted artifact, and cited evidence. Resolve the project slug from `.you-project` before writing.
|
|
22
|
+
2. Capture the immutable candidate Git revision with `git rev-parse HEAD`, recorded exactly as `git:<sha>`. If the worktree is dirty, record that fact in the Markdown review note; do not claim the candidate is committed.
|
|
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
|
+
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
|
+
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 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
|
+
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
|
+
|
|
29
|
+
## Required Markdown sections
|
|
30
|
+
|
|
31
|
+
Use: `Decision status`, `Candidate revision`, `North Star`, `Positioning`, `Horizons`, `Lanes`, `Evidence and provenance`, `Lineage`, `Human review`. State the unresolved question or explicitly say none.
|
|
32
|
+
|
|
33
|
+
## Update rule
|
|
34
|
+
|
|
35
|
+
Cosmetic HTML repairs may retain a version only if Markdown and JSON semantics and their candidate revision are unchanged. Any change to North Star, positioning, horizon outcome, lane scope/status, trust domain, or provenance requires a new proposed version.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>{{title}}</title><style>body{margin:0;background:#0d0d0d;color:#e8e4df;font:16px/1.6 Inter,system-ui,sans-serif}main{max-width:900px;margin:auto;padding:64px 28px}code,.meta,h1,h2{font-family:"JetBrains Mono",monospace}h1{font-size:clamp(2.4rem,7vw,5rem);line-height:1.05}.meta{color:#c46a3a;border-block:1px solid #332d28;padding:14px 0}h2{margin-top:3rem}a{color:#c46a3a}</style></head><body><main><p class="meta">{{artifact_id}} · {{status}} · candidate git:{{git_sha}} · {{horizon}} · review {{review_at}}</p><h1>{{title}}</h1><section><h2>North Star</h2><p>{{north_star}}</p></section><section><h2>Lanes</h2><p>{{lane_summary}}</p></section><section><h2>Evidence</h2><p>{{provenance_summary}}</p></section><section><h2>Human review</h2><p>{{review_request}}</p></section></main></body></html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://you.md/schemas/project-vision-artifacts/v1",
|
|
3
|
+
"schemaVersion": "you-md/project-vision-artifacts/v1",
|
|
4
|
+
"kind": "project-vision-artifacts",
|
|
5
|
+
"projectRef": "project:{{project_slug}}",
|
|
6
|
+
"northStar": { "statement": "{{north_star}}", "invariants": ["{{invariant}}"], "evidenceRefs": ["{{evidence_path}}"] },
|
|
7
|
+
"positioning": { "youmd": "{{youmd_positioning}}", "bamfAi": "{{bamf_ai_positioning}}", "bamfOs": "{{bamf_os_positioning}}" },
|
|
8
|
+
"horizons": {
|
|
9
|
+
"year": { "period": "{{year_period}}", "objective": "{{year_objective}}", "outcomes": ["{{year_outcome}}"], "focusRefs": ["{{focus_ref}}"], "status": "planned", "reviewAt": "{{year_review_at}}" },
|
|
10
|
+
"quarter": { "period": "{{quarter_period}}", "objective": "{{quarter_objective}}", "outcomes": ["{{quarter_outcome}}"], "focusRefs": ["{{focus_ref}}"], "status": "planned", "reviewAt": "{{quarter_review_at}}" },
|
|
11
|
+
"month": { "period": "{{month_period}}", "objective": "{{month_objective}}", "outcomes": ["{{month_outcome}}"], "focusRefs": ["{{focus_ref}}"], "status": "planned", "reviewAt": "{{month_review_at}}" },
|
|
12
|
+
"week": { "period": "{{week_period}}", "objective": "{{week_objective}}", "outcomes": ["{{week_outcome}}"], "focusRefs": ["{{focus_ref}}"], "status": "planned", "reviewAt": "{{week_review_at}}" }
|
|
13
|
+
},
|
|
14
|
+
"lanes": [{ "id": "{{lane_id}}", "name": "{{lane_name}}", "kind": "product", "ownerAgentRef": "agent:{{owner_agent}}", "scopeRefs": ["{{scope_ref}}"], "claimMode": "propose", "status": "planned", "dependsOn": [], "reviewAt": "{{lane_review_at}}" }],
|
|
15
|
+
"artifacts": [{ "id": "{{artifact_id}}", "title": "{{title}}", "family": "vision", "scopeRefs": ["{{scope_ref}}"], "horizon": "week", "version": 1, "candidateRevision": "git:{{git_sha}}", "status": "proposed", "trustDomain": "owner-private", "createdAt": "{{created_at}}", "reviewAt": "{{review_at}}", "formats": { "markdown": "{{markdown_path}}", "json": "{{json_path}}", "html": "{{html_path}}" }, "lineage": { "relation": "main", "parentVersionId": null, "main": true }, "provenance": ["{{evidence_path}}"] }],
|
|
16
|
+
"updatedAt": "{{created_at}}"
|
|
17
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# {{title}}
|
|
2
|
+
|
|
3
|
+
**Decision status:** proposed — human review required
|
|
4
|
+
**Candidate revision:** `git:{{git_sha}}`
|
|
5
|
+
**Artifact id / version:** `{{artifact_id}}` / {{version}}
|
|
6
|
+
**Review at:** {{review_at}}
|
|
7
|
+
|
|
8
|
+
## North Star
|
|
9
|
+
|
|
10
|
+
{{north_star}}
|
|
11
|
+
|
|
12
|
+
## Positioning
|
|
13
|
+
|
|
14
|
+
{{positioning}}
|
|
15
|
+
|
|
16
|
+
## Horizons
|
|
17
|
+
|
|
18
|
+
| Horizon | Objective | Outcomes | Review |
|
|
19
|
+
| --- | --- | --- | --- |
|
|
20
|
+
| Year | {{year_objective}} | {{year_outcomes}} | {{year_review_at}} |
|
|
21
|
+
| Quarter | {{quarter_objective}} | {{quarter_outcomes}} | {{quarter_review_at}} |
|
|
22
|
+
| Month | {{month_objective}} | {{month_outcomes}} | {{month_review_at}} |
|
|
23
|
+
| Week | {{week_objective}} | {{week_outcomes}} | {{week_review_at}} |
|
|
24
|
+
|
|
25
|
+
## Lanes
|
|
26
|
+
|
|
27
|
+
{{lanes}}
|
|
28
|
+
|
|
29
|
+
## Evidence and provenance
|
|
30
|
+
|
|
31
|
+
{{provenance}}
|
|
32
|
+
|
|
33
|
+
## Lineage
|
|
34
|
+
|
|
35
|
+
{{lineage}}
|
|
36
|
+
|
|
37
|
+
## Human review
|
|
38
|
+
|
|
39
|
+
{{review_request}}
|
|
@@ -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
|
+
}
|