From db6e7e29eaa5f8c90be97121567b405c2e6ca393 Mon Sep 17 00:00:00 2001
From: sarveshsea
Date: Sun, 2 Aug 2026 12:38:36 -0500
Subject: [PATCH 1/8] test: define brand manifest contract
---
.gitignore | 2 +
package-lock.json | 76 ++++++++++++++++++++
package.json | 18 +++++
tests/brand-manifest.test.mjs | 132 ++++++++++++++++++++++++++++++++++
4 files changed, 228 insertions(+)
create mode 100644 .gitignore
create mode 100644 package-lock.json
create mode 100644 package.json
create mode 100644 tests/brand-manifest.test.mjs
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d570088
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules/
+
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..a2de4d3
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,76 @@
+{
+ "name": "@memi-design/org-profile",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@memi-design/org-profile",
+ "version": "0.0.0",
+ "devDependencies": {
+ "ajv": "8.20.0"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz",
+ "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..d69e141
--- /dev/null
+++ b/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "@memi-design/org-profile",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "brand:check": "node scripts/validate-brand-manifest.mjs --check",
+ "brand:sync": "node scripts/validate-brand-manifest.mjs --write",
+ "test": "node --test",
+ "check": "npm run brand:check && npm test"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "devDependencies": {
+ "ajv": "8.20.0"
+ }
+}
diff --git a/tests/brand-manifest.test.mjs b/tests/brand-manifest.test.mjs
new file mode 100644
index 0000000..7844fa8
--- /dev/null
+++ b/tests/brand-manifest.test.mjs
@@ -0,0 +1,132 @@
+import assert from "node:assert/strict";
+import { readFile } from "node:fs/promises";
+import { spawnSync } from "node:child_process";
+import test from "node:test";
+import { fileURLToPath } from "node:url";
+import path from "node:path";
+
+import {
+ MANIFEST_RELATIVE_PATH,
+ SCHEMA_RELATIVE_PATH,
+ checkRepository,
+ renderManagedDocuments,
+ validateBrandPolicy,
+ validateManifestData,
+} from "../scripts/validate-brand-manifest.mjs";
+
+const repositoryRoot = path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ "..",
+);
+
+async function readJson(relativePath) {
+ return JSON.parse(
+ await readFile(path.join(repositoryRoot, relativePath), "utf8"),
+ );
+}
+
+test("canonical manifest satisfies its JSON Schema and brand policy", async () => {
+ const [manifest, schema] = await Promise.all([
+ readJson(MANIFEST_RELATIVE_PATH),
+ readJson(SCHEMA_RELATIVE_PATH),
+ ]);
+
+ assert.deepEqual(validateManifestData(manifest, schema), []);
+ assert.deepEqual(validateBrandPolicy(manifest), []);
+});
+
+test("manifest names the four canonical products and keeps Canvas in development", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const statuses = Object.fromEntries(
+ manifest.products.map(({ id, status }) => [id, status]),
+ );
+
+ assert.deepEqual(statuses, {
+ cli: "available",
+ studio: "available",
+ "design-skills": "available",
+ canvas: "development",
+ });
+ assert.equal(Number.isInteger(manifest.brandRevision), true);
+ assert.equal(manifest.brandRevision > 0, true);
+});
+
+test("schema rejects a product without a license", async () => {
+ const [manifest, schema] = await Promise.all([
+ readJson(MANIFEST_RELATIVE_PATH),
+ readJson(SCHEMA_RELATIVE_PATH),
+ ]);
+ const invalidManifest = structuredClone(manifest);
+ delete invalidManifest.products[0].license;
+
+ assert.match(
+ validateManifestData(invalidManifest, schema).join("\n"),
+ /license/,
+ );
+});
+
+test("policy rejects aliases that collide across products", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const invalidManifest = structuredClone(manifest);
+ invalidManifest.products[3].aliases = [
+ ...invalidManifest.products[3].aliases,
+ "Memi",
+ ];
+
+ assert.match(
+ validateBrandPolicy(invalidManifest).join("\n"),
+ /alias .*Memi.*cli.*canvas/i,
+ );
+});
+
+test("policy rejects personal namespaces in operational product URLs", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const invalidManifest = structuredClone(manifest);
+ invalidManifest.products[0].urls.documentation =
+ "https://github.com/sarveshsea/memi";
+
+ assert.match(
+ validateBrandPolicy(invalidManifest).join("\n"),
+ /personal or legacy URL/i,
+ );
+});
+
+test("managed documentation is synchronized with the manifest", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const renderedDocuments = renderManagedDocuments(manifest);
+
+ for (const [relativePath, expectedContent] of renderedDocuments) {
+ const actualContent = await readFile(
+ path.join(repositoryRoot, relativePath),
+ "utf8",
+ );
+ assert.equal(actualContent, expectedContent, `${relativePath} has drifted`);
+ }
+
+ assert.deepEqual(await checkRepository(repositoryRoot), []);
+});
+
+test("checked-in docs avoid stale pins and personal operational URLs", async () => {
+ const documentation = await Promise.all(
+ ["profile/README.md", "ORG_ARCHITECTURE.md", "brand/README.md"].map(
+ async (relativePath) =>
+ readFile(path.join(repositoryRoot, relativePath), "utf8"),
+ ),
+ );
+ const combined = documentation.join("\n");
+
+ assert.doesNotMatch(combined, /@memi-design\/cli@\d+\.\d+\.\d+/);
+ assert.doesNotMatch(combined, /https:\/\/github\.com\/sarveshsea\//);
+ assert.match(combined, /non-operational provenance/i);
+});
+
+test("validation CLI succeeds in check mode", () => {
+ const result = spawnSync(
+ process.execPath,
+ ["scripts/validate-brand-manifest.mjs", "--check"],
+ { cwd: repositoryRoot, encoding: "utf8" },
+ );
+
+ assert.equal(result.status, 0, result.stderr || result.stdout);
+ assert.match(result.stdout, /Brand manifest is valid and synchronized/);
+});
From ccde88343bbd9b1f012104588870383a7c3c854f Mon Sep 17 00:00:00 2001
From: sarveshsea
Date: Sun, 2 Aug 2026 12:52:48 -0500
Subject: [PATCH 2/8] test: cover brand policy review gaps
---
package.json | 3 +-
tests/brand-manifest.test.mjs | 105 +++++++++++++++++++++++++++++++++-
2 files changed, 105 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index d69e141..5395f1c 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,8 @@
"brand:check": "node scripts/validate-brand-manifest.mjs --check",
"brand:sync": "node scripts/validate-brand-manifest.mjs --write",
"test": "node --test",
- "check": "npm run brand:check && npm test"
+ "test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=80 --test-coverage-functions=80 --test-coverage-branches=80",
+ "check": "npm run brand:check && npm run test:coverage"
},
"engines": {
"node": ">=20"
diff --git a/tests/brand-manifest.test.mjs b/tests/brand-manifest.test.mjs
index 7844fa8..338d654 100644
--- a/tests/brand-manifest.test.mjs
+++ b/tests/brand-manifest.test.mjs
@@ -1,6 +1,14 @@
import assert from "node:assert/strict";
-import { readFile } from "node:fs/promises";
+import {
+ copyFile,
+ mkdir,
+ mkdtemp,
+ readFile,
+ rm,
+ writeFile,
+} from "node:fs/promises";
import { spawnSync } from "node:child_process";
+import { tmpdir } from "node:os";
import test from "node:test";
import { fileURLToPath } from "node:url";
import path from "node:path";
@@ -51,6 +59,18 @@ test("manifest names the four canonical products and keeps Canvas in development
assert.equal(manifest.brandRevision > 0, true);
});
+test("policy rejects missing, unexpected, and incorrectly staged products", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const invalidManifest = structuredClone(manifest);
+ invalidManifest.products[0].id = "unexpected-product";
+ invalidManifest.products[1].status = "development";
+
+ const errors = validateBrandPolicy(invalidManifest).join("\n");
+ assert.match(errors, /Missing canonical product cli/);
+ assert.match(errors, /Unexpected canonical product unexpected-product/);
+ assert.match(errors, /Product studio must have status available/);
+});
+
test("schema rejects a product without a license", async () => {
const [manifest, schema] = await Promise.all([
readJson(MANIFEST_RELATIVE_PATH),
@@ -65,6 +85,21 @@ test("schema rejects a product without a license", async () => {
);
});
+test("schema requires an honest status note for development products", async () => {
+ const [manifest, schema] = await Promise.all([
+ readJson(MANIFEST_RELATIVE_PATH),
+ readJson(SCHEMA_RELATIVE_PATH),
+ ]);
+ const invalidManifest = structuredClone(manifest);
+ const canvas = invalidManifest.products.find(({ id }) => id === "canvas");
+ delete canvas.statusNote;
+
+ assert.match(
+ validateManifestData(invalidManifest, schema).join("\n"),
+ /statusNote/,
+ );
+});
+
test("policy rejects aliases that collide across products", async () => {
const manifest = await readJson(MANIFEST_RELATIVE_PATH);
const invalidManifest = structuredClone(manifest);
@@ -91,6 +126,31 @@ test("policy rejects personal namespaces in operational product URLs", async ()
);
});
+test("policy rejects the legacy website as an operational product URL", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const invalidManifest = structuredClone(manifest);
+ invalidManifest.products[0].urls.documentation =
+ "https://memoire.cv/docs";
+
+ assert.match(
+ validateBrandPolicy(invalidManifest).join("\n"),
+ /personal or legacy URL/i,
+ );
+});
+
+test("policy rejects ambiguous or operational legacy exceptions", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const invalidManifest = structuredClone(manifest);
+ const duplicate = structuredClone(invalidManifest.legacyProvenanceAllowlist[0]);
+ duplicate.operational = true;
+ invalidManifest.legacyProvenanceAllowlist.push(duplicate);
+
+ const errors = validateBrandPolicy(invalidManifest).join("\n");
+ assert.match(errors, /allowlist id .* duplicated/i);
+ assert.match(errors, /allowlist value .* duplicated/i);
+ assert.match(errors, /must be non-operational/i);
+});
+
test("managed documentation is synchronized with the manifest", async () => {
const manifest = await readJson(MANIFEST_RELATIVE_PATH);
const renderedDocuments = renderManagedDocuments(manifest);
@@ -106,9 +166,49 @@ test("managed documentation is synchronized with the manifest", async () => {
assert.deepEqual(await checkRepository(repositoryRoot), []);
});
+test("repository check reports generated drift and personal URLs", async (context) => {
+ const temporaryRoot = await mkdtemp(path.join(tmpdir(), "memi-brand-test-"));
+ context.after(() => rm(temporaryRoot, { recursive: true, force: true }));
+ const copiedPaths = [
+ MANIFEST_RELATIVE_PATH,
+ SCHEMA_RELATIVE_PATH,
+ "profile/README.md",
+ "ORG_ARCHITECTURE.md",
+ "brand/README.md",
+ "OPEN_SOURCE.md",
+ "CONTRIBUTING.md",
+ "GOVERNANCE.md",
+ "SECURITY.md",
+ "SUPPORT.md",
+ "CODE_OF_CONDUCT.md",
+ ];
+
+ for (const relativePath of copiedPaths) {
+ const target = path.join(temporaryRoot, relativePath);
+ await mkdir(path.dirname(target), { recursive: true });
+ await copyFile(path.join(repositoryRoot, relativePath), target);
+ }
+
+ const profilePath = path.join(temporaryRoot, "profile/README.md");
+ await writeFile(
+ profilePath,
+ `${await readFile(profilePath, "utf8")}\nhttps://github.com/sarveshsea/legacy\n`,
+ );
+
+ const errors = (await checkRepository(temporaryRoot)).join("\n");
+ assert.match(errors, /profile\/README\.md is not synchronized/);
+ assert.match(errors, /profile\/README\.md contains a personal operational URL/);
+});
+
test("checked-in docs avoid stale pins and personal operational URLs", async () => {
const documentation = await Promise.all(
- ["profile/README.md", "ORG_ARCHITECTURE.md", "brand/README.md"].map(
+ [
+ "profile/README.md",
+ "ORG_ARCHITECTURE.md",
+ "brand/README.md",
+ "SECURITY.md",
+ "SUPPORT.md",
+ ].map(
async (relativePath) =>
readFile(path.join(repositoryRoot, relativePath), "utf8"),
),
@@ -117,6 +217,7 @@ test("checked-in docs avoid stale pins and personal operational URLs", async ()
assert.doesNotMatch(combined, /@memi-design\/cli@\d+\.\d+\.\d+/);
assert.doesNotMatch(combined, /https:\/\/github\.com\/sarveshsea\//);
+ assert.doesNotMatch(combined, /https:\/\/(?:www\.)?memoire\.cv\b/);
assert.match(combined, /non-operational provenance/i);
});
From 1ac2699f96999cde5031f5463d15cfdc16c76d74 Mon Sep 17 00:00:00 2001
From: sarveshsea
Date: Sun, 2 Aug 2026 12:57:00 -0500
Subject: [PATCH 3/8] feat: establish canonical brand manifest
---
.github/ISSUE_TEMPLATE/bug.yml | 2 +-
CODE_OF_CONDUCT.md | 5 +-
CONTRIBUTING.md | 8 +-
OPEN_SOURCE.md | 10 +-
ORG_ARCHITECTURE.md | 66 +++----
SECURITY.md | 7 +-
SUPPORT.md | 3 +-
brand/README.md | 52 ++++-
brand/brand-manifest.v1.json | 199 +++++++++++++++++++
brand/brand-manifest.v1.schema.json | 151 +++++++++++++++
profile/README.md | 56 +++---
scripts/lib/render-brand-documents.mjs | 254 +++++++++++++++++++++++++
scripts/validate-brand-manifest.mjs | 252 ++++++++++++++++++++++++
tests/brand-manifest.test.mjs | 8 +-
14 files changed, 982 insertions(+), 91 deletions(-)
create mode 100644 brand/brand-manifest.v1.json
create mode 100644 brand/brand-manifest.v1.schema.json
create mode 100644 scripts/lib/render-brand-documents.mjs
create mode 100644 scripts/validate-brand-manifest.mjs
diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index a60b8ba..bb0177a 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -19,7 +19,7 @@ body:
id: version
attributes:
label: Version or commit
- placeholder: 2.6.3 or a full commit SHA
+ placeholder: latest release or a full commit SHA
validations:
required: true
- type: input
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index bccc69c..775b4b0 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -28,9 +28,8 @@ requests, release channels, and public events where someone represents Memi.
For conduct on GitHub, use GitHub's private
[report-abuse path](https://support.github.com/contact/report-abuse). To request
-maintainer follow-up, mention the release owner
-[`@sarveshsea`](https://github.com/sarveshsea) without posting sensitive details;
-a private channel will be established before evidence is shared. Include links,
+maintainer follow-up, use the private contact route documented in
+[SECURITY.md](SECURITY.md) without posting sensitive details. Include links,
dates, context, and any immediate safety concern only through that private
channel. Do not open a public issue containing sensitive personal details.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6022cdb..824769c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,9 +17,11 @@ Advance permission is not required for an unassigned `good first issue`.
## Choose the right repository
- Core audits, CLI, MCP, GitHub Action, and focused skills: `memi`.
-- Canonical design skill catalog: `design-skills`.
+- Canonical design workflow catalog: `design-skills`.
- Native macOS companion: `memi-studio`.
-- Reproducible web examples: `design-sandbox`.
+- In-development local-first canvas: `memi-canvas`.
+- Reproducible examples and integrations: the repository that owns that
+ bounded proof.
- Bugs in a proof fork: report them in that fork and link the upstream source when relevant.
Start with an issue for broad behavior or architecture changes. Small documentation, fixture, and focused bug fixes may go directly to a pull request.
@@ -43,6 +45,8 @@ a pull request:
- Cite the repository file, route, or rendered evidence behind a design finding.
- Retain licenses and attribution for adapted work.
- Keep generated mirrors synchronized with their declared source of truth.
+- Keep product identity synchronized with
+ [`brand/brand-manifest.v1.json`](brand/brand-manifest.v1.json).
- Use conventional commits such as `feat:`, `fix:`, `docs:`, `test:`, and `chore:`.
Each repository may define additional checks in its own contributing guide.
diff --git a/OPEN_SOURCE.md b/OPEN_SOURCE.md
index 123eee4..b2cf78f 100644
--- a/OPEN_SOURCE.md
+++ b/OPEN_SOURCE.md
@@ -6,7 +6,8 @@ Memi is developed in public around a small number of supported product surfaces.
1. Use the first-audit command and report unclear output or missing evidence.
2. Improve a focused skill, fixture, example, or documentation path.
-3. Reproduce a design-engineering problem in `design-sandbox`.
+3. Reproduce a design-engineering problem in the smallest relevant product or
+ proof repository.
4. Propose a cross-repository change in `memi` Discussions before implementing it.
5. Help review accessibility, platform compatibility, provenance, and licensing.
@@ -22,4 +23,9 @@ Issues labeled `good first issue` are scoped for a first contribution. Issues la
## Repository lifecycle
-Only supported products, distribution surfaces, and reproducible proofs belong in the organization. Incubating work is labeled clearly; abandoned or superseded work is archived with a replacement or end-of-life note. The current classification is documented in [ORG_ARCHITECTURE.md](ORG_ARCHITECTURE.md).
+Only supported products, distribution surfaces, and reproducible proofs belong
+in the organization. Development work is labeled clearly; abandoned or
+superseded work is archived with a replacement or end-of-life notice. The
+current classification is generated from
+[`brand/brand-manifest.v1.json`](brand/brand-manifest.v1.json) into
+[ORG_ARCHITECTURE.md](ORG_ARCHITECTURE.md).
diff --git a/ORG_ARCHITECTURE.md b/ORG_ARCHITECTURE.md
index 5c4f529..61cb9af 100644
--- a/ORG_ARCHITECTURE.md
+++ b/ORG_ARCHITECTURE.md
@@ -1,39 +1,33 @@
# Memi Organization Architecture
-This document defines which repositories belong in `memi-design`, how they are classified, and what proof is required before they are presented as official.
+This document defines the supported product surfaces in `memi-design`, their release boundaries, and the proof required before a repository is presented as official.
-## Repository tiers
+The canonical machine-readable source is [`brand/brand-manifest.v1.json`](brand/brand-manifest.v1.json). This page is generated from brand revision **1**; run `npm run brand:sync` after changing the manifest.
-### Products
+## Product surfaces
-| Repository | Responsibility | Primary release |
-| --- | --- | --- |
-| `memi` | Audit engine, CLI, MCP, Action, focused skills | npm and GitHub Releases |
-| `memi-studio` | Native macOS companion | GitHub Releases and Homebrew |
-| `design-skills` | Canonical governed skill catalog | GitHub release and Agent Skills install |
-| `design-sandbox` | Runnable web proof and design-engineering lab | Hosted preview and source |
+| Product ID | Product | Status | Responsibility | License |
+| --- | --- | --- | --- | --- |
+| `cli` | [Memi CLI](https://github.com/memi-design/memi) | Available | Read-only design engineering audit and skill layer for coding agents. | [MIT](https://github.com/memi-design/memi/blob/main/LICENSE) |
+| `studio` | [Memi Studio](https://github.com/memi-design/memi-studio) | Available | Native macOS companion for supervised agent workflows and artifact review. | [FSL-1.1-ALv2](https://github.com/memi-design/memi-studio/blob/main/LICENSE); Apache-2.0 on 2028-05-09 |
+| `design-skills` | [Memi Design Skills](https://github.com/memi-design/design-skills) | Available | Governed catalog of portable and capability-gated design workflows for coding agents. | [MIT](https://github.com/memi-design/design-skills/blob/main/LICENSE) |
+| `canvas` | [Memi Canvas](https://github.com/memi-design/memi-canvas) | In development | Local-first canvas workbench for understanding, creating, and verifying software interfaces. | [Apache-2.0](https://github.com/memi-design/memi-canvas/blob/main/LICENSE) |
+
+### Canvas release boundary
-### Distribution
+Open-source M0 development snapshot; not yet a production importer or source editor. Canvas must remain labeled **In development** until its repository's capture, provider, source-write, security, recovery, and release gates are satisfied.
-| Repository | Responsibility |
-| --- | --- |
-| `homebrew-memi` | Formula and cask tap |
-| `audit-frontend-design` | Focused directory and install surface |
-| `remember-design-system` | Focused directory and install surface |
-| `enforce-design-ci` | Focused directory and install surface |
-| `memoire-web` | Website and public documentation deployment |
+## Distribution surfaces
-The focused skill repositories are generated mirrors. Their source of truth remains `memi`.
+- `homebrew-memi` owns the canonical Homebrew formula and cask tap.
+- Focused skill repositories are install and discovery mirrors; they must identify their canonical source and remain synchronized.
+- The organization profile and [public website](https://memoire.cv) are projections of the brand and release manifests, not independent version authorities.
-### Labs and proofs
+No personal namespace is an operational source, install, support, container, or release route.
-Labs exist to demonstrate one integration or design-engineering capability. They are not separate product lines.
+## Labs and integration proofs
-| Repository | Proof contract |
-| --- | --- |
-| `mermaid-jam` | Local-only FigJam diagram tooling with a verified public Pages build |
-| `ripple-image-transitions` | SwiftUI and Metal audit integration with retained upstream attribution |
-| `chatbot` | Real shadcn application with a pinned design-CI workflow |
+Labs demonstrate one bounded integration or design-engineering capability. They are not separate product lines and must preserve upstream attribution. A proof becomes official only when its README states the proof contract, the public path is runnable, and current verification evidence exists.
## Repository contract
@@ -41,7 +35,7 @@ Every official public repository must have:
1. A one-sentence job and one first-run path.
2. An explicit license and retained third-party attribution.
-3. A maintained README with current organization links.
+3. A maintained README whose product identity matches the brand manifest.
4. CI appropriate to its runtime and a pinned dependency policy.
5. Security reporting through the organization policy.
6. Topics, description, homepage, and repository visibility set deliberately.
@@ -52,12 +46,14 @@ Every official public repository must have:
| Surface | Source of truth | Identity constraint |
| --- | --- | --- |
-| npm `@memi-design/cli` | `memi/release-manifest.json` | Trusted Publisher must target `memi-design/memi` |
+| npm package | `memi/release-manifest.json` | Trusted Publisher targets `memi-design/memi` |
| GitHub Action | `memi/action.yml` | Consumers pin a full commit SHA |
-| MCP Registry | `memi/server.json` | Existing server identity remains compatible during migration |
-| GHCR | Core release workflow | New releases publish to `ghcr.io/memi-design/memi`; the personal namespace remains historical |
-| Homebrew | `homebrew-memi` | Canonical tap is `memi-design/memi` |
-| Website | `memoire-web` | Version and release copy are generated from the core manifest |
+| MCP Registry | `memi/server.json` | Current server identity remains compatible during migration |
+| Container images | Core release workflow | New releases publish only to the organization namespace |
+| Homebrew | `homebrew-memi` | The canonical tap is owned by `memi-design` |
+| Product identity | `brand/brand-manifest.v1.json` | Names, statuses, URLs, licenses, icons, and aliases use one brand revision |
+
+Release versions and public parity evidence stay in the core release manifest. A published artifact is not described as parity-verified until its independent verification gate passes.
## Transfer gate
@@ -69,13 +65,13 @@ Before moving a repository:
- update the canonical local remote;
- rerun clean installs and public-link checks after the move.
-Any repository with a live Pages environment moves only after its external identity is ready.
+Any repository with a live release or Pages environment moves only after its external identity is ready. Historical personal namespaces may remain only inside the non-operational provenance allowlist.
## Lifecycle
-- **Official:** actively maintained and part of the supported product path.
+- **Available:** supported now through at least one documented public route.
+- **Development:** implementation is public, but required product or release proof remains incomplete.
- **Proof:** maintained integration with reproducible evidence.
-- **Incubating:** incomplete experiment; not pinned or advertised as supported.
- **Archived:** read-only historical reference with a replacement or end-of-life notice.
-Repository count is not a growth metric. A repository belongs in the organization only when it makes the product easier to understand, install, verify, or extend.
+Repository count is not a growth metric. A repository belongs in the organization only when it makes a supported product easier to understand, install, verify, or extend.
diff --git a/SECURITY.md b/SECURITY.md
index 40b1dce..67fc5ed 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -4,7 +4,11 @@
Please use GitHub private vulnerability reporting on the affected repository when available. Do not open a public issue for credentials, arbitrary file access, archive traversal, command execution, SSRF, publisher compromise, or supply-chain vulnerabilities.
-If private reporting is unavailable, contact the maintainer through the security contact listed at [memoire.cv](https://memoire.cv) and include the repository, affected version, reproduction, impact, and suggested mitigation.
+If private reporting is unavailable, contact the maintainer through the
+security contact listed on the canonical [Memi website](https://memoire.cv).
+Do not include exploit details until a private channel is established. Then
+include the repository, affected release, reproduction, impact, and suggested
+mitigation.
## Supported releases
@@ -22,4 +26,3 @@ High-priority reports include:
- secret exposure through logs, reports, or generated artifacts.
Please allow a reasonable remediation window before public disclosure.
-
diff --git a/SUPPORT.md b/SUPPORT.md
index c172675..1d87263 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -3,7 +3,6 @@
- Usage questions and implementation discussion: [Memi Discussions](https://github.com/memi-design/memi/discussions).
- Reproducible bugs: open an issue in the repository that owns the behavior.
- Security vulnerabilities: follow [SECURITY.md](SECURITY.md).
-- General documentation: [memoire.cv](https://memoire.cv).
+- General documentation: [Memi website](https://memoire.cv).
Include the operating system, runtime version, Memi version, exact command, and minimal reproduction. Remove credentials and private source content before posting.
-
diff --git a/brand/README.md b/brand/README.md
index 5564d67..4a06e3c 100644
--- a/brand/README.md
+++ b/brand/README.md
@@ -1,24 +1,60 @@
-# Memi Brand Assets
+# Memi Brand Assets and Manifest
-These are the canonical organization-level assets for Memi.
+This directory contains the canonical organization assets and the versioned product identity contract for Memi.
+
+## Sources of truth
+
+- [`brand-manifest.v1.json`](brand-manifest.v1.json) records brand revision **1** and the canonical product IDs, names, roles, statuses, URLs, licenses, icons, aliases, and legacy exceptions.
+- [`brand-manifest.v1.schema.json`](brand-manifest.v1.schema.json) is the JSON Schema for manifest version 1.
+- [Memi's public website](https://memoire.cv) is a current organization surface; its domain is not a legacy alias.
+- `npm run brand:check` validates the schema, policy invariants, and synchronized documentation.
+- `npm run brand:sync` regenerates the organization profile and architecture documents after an intentional manifest edit.
+
+Consumers should reject unsupported `schemaVersion` values. Increment `brandRevision` for every identity change that downstream repositories must adopt.
+
+## Product registry
+
+| Product ID | Canonical name | Status | License | Accepted aliases | Primary icon |
+| --- | --- | --- | --- | --- | --- |
+| `cli` | [Memi CLI](https://github.com/memi-design/memi) | Available | [MIT](https://github.com/memi-design/memi/blob/main/LICENSE) | `Memi`, `Memi Engine`, `Mémoire`, `Mémoire CLI`, `Mémoire Engine` | [memi-mark](https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png) |
+| `studio` | [Memi Studio](https://github.com/memi-design/memi-studio) | Available | [FSL-1.1-ALv2](https://github.com/memi-design/memi-studio/blob/main/LICENSE) | `Mémoire Studio` | [studio-app-icon](https://raw.githubusercontent.com/memi-design/memi-studio/main/docs/assets/memi-icon-dark.png) |
+| `design-skills` | [Memi Design Skills](https://github.com/memi-design/design-skills) | Available | [MIT](https://github.com/memi-design/design-skills/blob/main/LICENSE) | `Design Skills`, `Memi Skills`, `Mémoire Design Skills` | [memi-mark](https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png) |
+| `canvas` | [Memi Canvas](https://github.com/memi-design/memi-canvas) | In development | [Apache-2.0](https://github.com/memi-design/memi-canvas/blob/main/LICENSE) | `Mémoire Canvas` | [memi-mark](https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png) |
+
+Aliases exist for search, migration, and compatibility. They do not replace the canonical name on current release, install, support, or documentation surfaces.
+
+## Legacy and provenance allowlist
+
+Legacy values are permitted only as **non-operational provenance**. They must never be used as a current source, install, download, support, package-publish, container-publish, or release destination. Exact machine-match values live only in the manifest so generated public documentation does not revive personal operational links.
+
+| Allowlist ID | Historical identity | Kind | Permitted contexts | Reason |
+| --- | --- | --- | --- | --- |
+| `legacy-memoire-name` | Legacy Mémoire name | `name` | `historical-release`, `license-provenance` | Preserves accurate attribution for releases and source records created before this brand revision. |
+| `legacy-personal-github` | Legacy personal GitHub namespace | `url-prefix` | `historical-release`, `license-provenance`, `immutable-archive` | May identify immutable historical artifacts or upstream provenance, but never a current install, support, source, or release route. |
+| `legacy-personal-ghcr` | Legacy personal container namespace | `url-prefix` | `historical-release`, `immutable-archive` | May identify immutable historical container provenance, but never the target for a current release. |
+| `legacy-memoire-package-scope` | Legacy Mémoire package scope | `package-prefix` | `historical-release`, `license-provenance` | Records historical package identities without presenting them as current installation targets. |
+| `legacy-studio-asset-prefix` | Legacy Studio release asset prefix | `asset-prefix` | `historical-release`, `immutable-archive` | Existing signed release assets retain their published filenames for checksum and provenance continuity. |
+
+Adding an entry requires a bounded context, a provenance reason, and `operational: false`. Prefer removing a legacy reference when immutable provenance does not require it.
+
+## Assets
| Asset | Use | Size |
| --- | --- | --- |
| `memi-avatar.png` | GitHub organization avatar and square profile surfaces | 512 × 512 |
-| `memi-social-preview.jpg` | GitHub social previews and organization banners | 1280 × 640 |
+| `memi-social-preview.jpg` | GitHub social previews | 1280 × 640 |
| `memi-brand-banner.png` | Repository README, npm, and organization-profile banner | 1983 × 793 |
## Usage
- Keep the pixel-heart mark centered and uncropped.
- Use the avatar on black or near-black surfaces.
-- Preserve the banner's 2:1 composition; do not place text over the central mark.
-- Preserve the supplied banner's 2.5:1 composition and its centered wordmark; do not crop or overlay text.
-- Product-specific diagrams and screenshots may use their own visual language, but should link back to these organization assets.
+- Preserve the social preview's 2:1 composition.
+- Preserve the supplied banner's 2.5:1 composition and centered wordmark; do not crop, overlay text, or substitute a product alias.
+- Product-specific diagrams and screenshots may use their own visual language, but their product identity must match the manifest.
## Provenance
The source artwork was supplied by the project owner. The organization variants were produced for Memi by replacing or extending the original backgrounds with a near-black field while preserving the supplied pixel-mosaic forms. No third-party marks or assets are included.
-Copyright in the supplied artwork is retained by the project owner. Refer to
-[TRADEMARKS.md](TRADEMARKS.md) before reusing the Memi name or brand assets.
+Copyright in the supplied artwork is retained by the project owner. Refer to [`TRADEMARKS.md`](TRADEMARKS.md) before reusing the Memi name or brand assets.
diff --git a/brand/brand-manifest.v1.json b/brand/brand-manifest.v1.json
new file mode 100644
index 0000000..26174b0
--- /dev/null
+++ b/brand/brand-manifest.v1.json
@@ -0,0 +1,199 @@
+{
+ "$schema": "./brand-manifest.v1.schema.json",
+ "schemaVersion": 1,
+ "brandRevision": 1,
+ "updatedAt": "2026-08-02",
+ "organization": {
+ "id": "memi-design",
+ "name": "Memi",
+ "tagline": "The design layer for agentic AI.",
+ "urls": {
+ "github": "https://github.com/memi-design",
+ "website": "https://memoire.cv"
+ }
+ },
+ "products": [
+ {
+ "id": "cli",
+ "name": "Memi CLI",
+ "role": "Read-only design engineering audit and skill layer for coding agents.",
+ "status": "available",
+ "urls": {
+ "repository": "https://github.com/memi-design/memi",
+ "documentation": "https://github.com/memi-design/memi/blob/main/docs/README.md",
+ "package": "https://www.npmjs.com/package/@memi-design/cli"
+ },
+ "license": {
+ "spdx": "MIT",
+ "name": "MIT License",
+ "url": "https://github.com/memi-design/memi/blob/main/LICENSE"
+ },
+ "icons": [
+ {
+ "id": "memi-mark",
+ "purpose": "primary",
+ "url": "https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png",
+ "alt": "Memi pixel-heart mark"
+ }
+ ],
+ "aliases": [
+ "Memi",
+ "Memi Engine",
+ "Mémoire",
+ "Mémoire CLI",
+ "Mémoire Engine"
+ ]
+ },
+ {
+ "id": "studio",
+ "name": "Memi Studio",
+ "role": "Native macOS companion for supervised agent workflows and artifact review.",
+ "status": "available",
+ "urls": {
+ "repository": "https://github.com/memi-design/memi-studio",
+ "documentation": "https://github.com/memi-design/memi-studio#readme",
+ "download": "https://github.com/memi-design/memi-studio/releases/latest"
+ },
+ "license": {
+ "spdx": "FSL-1.1-ALv2",
+ "name": "Functional Source License 1.1 with Apache-2.0 future license",
+ "url": "https://github.com/memi-design/memi-studio/blob/main/LICENSE",
+ "futureLicense": {
+ "spdx": "Apache-2.0",
+ "effectiveDate": "2028-05-09",
+ "url": "https://github.com/memi-design/memi-studio/blob/main/LICENSE"
+ }
+ },
+ "icons": [
+ {
+ "id": "studio-app-icon",
+ "purpose": "app",
+ "url": "https://raw.githubusercontent.com/memi-design/memi-studio/main/docs/assets/memi-icon-dark.png",
+ "alt": "Memi Studio app icon"
+ }
+ ],
+ "aliases": [
+ "Mémoire Studio"
+ ]
+ },
+ {
+ "id": "design-skills",
+ "name": "Memi Design Skills",
+ "role": "Governed catalog of portable and capability-gated design workflows for coding agents.",
+ "status": "available",
+ "urls": {
+ "repository": "https://github.com/memi-design/design-skills",
+ "documentation": "https://github.com/memi-design/design-skills#readme",
+ "install": "https://skills.sh/memi-design/design-skills"
+ },
+ "license": {
+ "spdx": "MIT",
+ "name": "MIT License",
+ "url": "https://github.com/memi-design/design-skills/blob/main/LICENSE"
+ },
+ "icons": [
+ {
+ "id": "memi-mark",
+ "purpose": "primary",
+ "url": "https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png",
+ "alt": "Memi pixel-heart mark"
+ }
+ ],
+ "aliases": [
+ "Design Skills",
+ "Memi Skills",
+ "Mémoire Design Skills"
+ ]
+ },
+ {
+ "id": "canvas",
+ "name": "Memi Canvas",
+ "role": "Local-first canvas workbench for understanding, creating, and verifying software interfaces.",
+ "status": "development",
+ "statusNote": "Open-source M0 development snapshot; not yet a production importer or source editor.",
+ "urls": {
+ "repository": "https://github.com/memi-design/memi-canvas",
+ "documentation": "https://github.com/memi-design/memi-canvas#readme"
+ },
+ "license": {
+ "spdx": "Apache-2.0",
+ "name": "Apache License 2.0",
+ "url": "https://github.com/memi-design/memi-canvas/blob/main/LICENSE"
+ },
+ "icons": [
+ {
+ "id": "memi-mark",
+ "purpose": "primary",
+ "url": "https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png",
+ "alt": "Memi pixel-heart mark"
+ }
+ ],
+ "aliases": [
+ "Mémoire Canvas"
+ ]
+ }
+ ],
+ "legacyProvenanceAllowlist": [
+ {
+ "id": "legacy-memoire-name",
+ "kind": "name",
+ "label": "Legacy Mémoire name",
+ "value": "Mémoire",
+ "permittedContexts": [
+ "historical-release",
+ "license-provenance"
+ ],
+ "operational": false,
+ "reason": "Preserves accurate attribution for releases and source records created before this brand revision."
+ },
+ {
+ "id": "legacy-personal-github",
+ "kind": "url-prefix",
+ "label": "Legacy personal GitHub namespace",
+ "value": "https://github.com/sarveshsea/",
+ "permittedContexts": [
+ "historical-release",
+ "license-provenance",
+ "immutable-archive"
+ ],
+ "operational": false,
+ "reason": "May identify immutable historical artifacts or upstream provenance, but never a current install, support, source, or release route."
+ },
+ {
+ "id": "legacy-personal-ghcr",
+ "kind": "url-prefix",
+ "label": "Legacy personal container namespace",
+ "value": "https://ghcr.io/sarveshsea/",
+ "permittedContexts": [
+ "historical-release",
+ "immutable-archive"
+ ],
+ "operational": false,
+ "reason": "May identify immutable historical container provenance, but never the target for a current release."
+ },
+ {
+ "id": "legacy-memoire-package-scope",
+ "kind": "package-prefix",
+ "label": "Legacy Mémoire package scope",
+ "value": "@memoire/",
+ "permittedContexts": [
+ "historical-release",
+ "license-provenance"
+ ],
+ "operational": false,
+ "reason": "Records historical package identities without presenting them as current installation targets."
+ },
+ {
+ "id": "legacy-studio-asset-prefix",
+ "kind": "asset-prefix",
+ "label": "Legacy Studio release asset prefix",
+ "value": "Memoire.Studio_",
+ "permittedContexts": [
+ "historical-release",
+ "immutable-archive"
+ ],
+ "operational": false,
+ "reason": "Existing signed release assets retain their published filenames for checksum and provenance continuity."
+ }
+ ]
+}
diff --git a/brand/brand-manifest.v1.schema.json b/brand/brand-manifest.v1.schema.json
new file mode 100644
index 0000000..71d1c1d
--- /dev/null
+++ b/brand/brand-manifest.v1.schema.json
@@ -0,0 +1,151 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://raw.githubusercontent.com/memi-design/.github/main/brand/brand-manifest.v1.schema.json",
+ "title": "Memi brand manifest v1",
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["$schema", "schemaVersion", "brandRevision", "updatedAt", "organization", "products", "legacyProvenanceAllowlist"],
+ "properties": {
+ "$schema": { "const": "./brand-manifest.v1.schema.json" },
+ "schemaVersion": { "const": 1 },
+ "brandRevision": { "type": "integer", "minimum": 1 },
+ "updatedAt": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
+ "organization": { "$ref": "#/$defs/organization" },
+ "products": {
+ "type": "array",
+ "minItems": 4,
+ "maxItems": 4,
+ "items": { "$ref": "#/$defs/product" }
+ },
+ "legacyProvenanceAllowlist": {
+ "type": "array",
+ "minItems": 1,
+ "items": { "$ref": "#/$defs/legacyEntry" }
+ }
+ },
+ "$defs": {
+ "httpsUrl": { "type": "string", "pattern": "^https://[^\\s]+$" },
+ "slug": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" },
+ "organization": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["id", "name", "tagline", "urls"],
+ "properties": {
+ "id": { "$ref": "#/$defs/slug" },
+ "name": { "type": "string", "minLength": 1 },
+ "tagline": { "type": "string", "minLength": 1 },
+ "urls": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["github", "website"],
+ "properties": {
+ "github": { "$ref": "#/$defs/httpsUrl" },
+ "website": { "$ref": "#/$defs/httpsUrl" }
+ }
+ }
+ }
+ },
+ "product": {
+ "type": "object",
+ "additionalProperties": false,
+ "allOf": [
+ {
+ "if": {
+ "properties": { "status": { "const": "development" } },
+ "required": ["status"]
+ },
+ "then": {
+ "properties": {
+ "statusNote": { "type": "string", "minLength": 1 }
+ },
+ "required": ["statusNote"]
+ }
+ }
+ ],
+ "required": ["id", "name", "role", "status", "urls", "license", "icons", "aliases"],
+ "properties": {
+ "id": { "$ref": "#/$defs/slug" },
+ "name": { "type": "string", "minLength": 1 },
+ "role": { "type": "string", "minLength": 1 },
+ "status": { "enum": ["available", "development"] },
+ "statusNote": { "type": "string", "minLength": 1 },
+ "urls": { "$ref": "#/$defs/productUrls" },
+ "license": { "$ref": "#/$defs/license" },
+ "icons": {
+ "type": "array",
+ "minItems": 1,
+ "items": { "$ref": "#/$defs/icon" }
+ },
+ "aliases": {
+ "type": "array",
+ "minItems": 1,
+ "uniqueItems": true,
+ "items": { "type": "string", "minLength": 1 }
+ }
+ }
+ },
+ "productUrls": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["repository"],
+ "properties": {
+ "repository": { "$ref": "#/$defs/httpsUrl" },
+ "documentation": { "$ref": "#/$defs/httpsUrl" },
+ "package": { "$ref": "#/$defs/httpsUrl" },
+ "download": { "$ref": "#/$defs/httpsUrl" },
+ "install": { "$ref": "#/$defs/httpsUrl" }
+ }
+ },
+ "license": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["spdx", "name", "url"],
+ "properties": {
+ "spdx": { "type": "string", "minLength": 1 },
+ "name": { "type": "string", "minLength": 1 },
+ "url": { "$ref": "#/$defs/httpsUrl" },
+ "futureLicense": { "$ref": "#/$defs/futureLicense" }
+ }
+ },
+ "futureLicense": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["spdx", "effectiveDate", "url"],
+ "properties": {
+ "spdx": { "type": "string", "minLength": 1 },
+ "effectiveDate": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" },
+ "url": { "$ref": "#/$defs/httpsUrl" }
+ }
+ },
+ "icon": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["id", "purpose", "url", "alt"],
+ "properties": {
+ "id": { "$ref": "#/$defs/slug" },
+ "purpose": { "enum": ["primary", "app", "mark"] },
+ "url": { "$ref": "#/$defs/httpsUrl" },
+ "alt": { "type": "string", "minLength": 1 }
+ }
+ },
+ "legacyEntry": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["id", "kind", "label", "value", "permittedContexts", "operational", "reason"],
+ "properties": {
+ "id": { "$ref": "#/$defs/slug" },
+ "kind": { "enum": ["name", "url-prefix", "package-prefix", "asset-prefix"] },
+ "label": { "type": "string", "minLength": 1 },
+ "value": { "type": "string", "minLength": 1 },
+ "permittedContexts": {
+ "type": "array",
+ "minItems": 1,
+ "uniqueItems": true,
+ "items": { "enum": ["historical-release", "license-provenance", "immutable-archive"] }
+ },
+ "operational": { "const": false },
+ "reason": { "type": "string", "minLength": 1 }
+ }
+ }
+ }
+}
diff --git a/profile/README.md b/profile/README.md
index ef7ed66..10373b7 100644
--- a/profile/README.md
+++ b/profile/README.md
@@ -1,67 +1,59 @@
-
+
-
-
+
# Memi
-Read-only design engineering for coding agents.
+The design layer for agentic AI.
-Memi gives Codex, Claude Code, Cursor, Grok Build, and MCP clients file-anchored interface evidence before they edit UI.
+Memi gives coding agents file-anchored design evidence, governed design workflows, a supervised native workbench, and an emerging local-first canvas.
+
+## Start with the CLI
+
+Run a read-only audit in any frontend repository:
```bash
-npx -y @memi-design/cli@2.6.3 diagnose . --json --no-write --fail-on none
+npx -y @memi-design/cli@latest diagnose . --json --no-write --fail-on none
```
No account, API key, Figma file, global install, or daemon is required for the first audit.
-## Start here
+## Products
-| Repository | Role |
-| --- | --- |
-| [`memi`](https://github.com/memi-design/memi) | Core CLI, MCP server, GitHub Action, focused Agent Skills, and audit engine |
-| [`design-skills`](https://github.com/memi-design/design-skills) | Governed catalog of 94 design, research, craft, generation, and Figma skills |
-| [`memi-studio`](https://github.com/memi-design/memi-studio) | Native macOS companion for supervised agent workflows |
-| [`design-sandbox`](https://github.com/memi-design/design-sandbox) | Runnable Next.js proof environment for design audits and integrations |
+| Product | Status | Role | Public surfaces |
+| --- | --- | --- | --- |
+| [Memi CLI](https://github.com/memi-design/memi) | Available | Read-only design engineering audit and skill layer for coding agents. | [Repository](https://github.com/memi-design/memi) · [Docs](https://github.com/memi-design/memi/blob/main/docs/README.md) · [npm](https://www.npmjs.com/package/@memi-design/cli) |
+| [Memi Studio](https://github.com/memi-design/memi-studio) | Available | Native macOS companion for supervised agent workflows and artifact review. | [Repository](https://github.com/memi-design/memi-studio) · [Docs](https://github.com/memi-design/memi-studio#readme) · [Download](https://github.com/memi-design/memi-studio/releases/latest) |
+| [Memi Design Skills](https://github.com/memi-design/design-skills) | Available | Governed catalog of portable and capability-gated design workflows for coding agents. | [Repository](https://github.com/memi-design/design-skills) · [Docs](https://github.com/memi-design/design-skills#readme) · [Install](https://skills.sh/memi-design/design-skills) |
+| [Memi Canvas](https://github.com/memi-design/memi-canvas) | In development | Local-first canvas workbench for understanding, creating, and verifying software interfaces. | [Repository](https://github.com/memi-design/memi-canvas) · [Docs](https://github.com/memi-design/memi-canvas#readme) |
-## Focused Agent Skills
+**Canvas boundary:** Open-source M0 development snapshot; not yet a production importer or source editor. Its current tests and deterministic demo evidence are engineering proof, not a claim of production readiness.
-- [`audit-frontend-design`](https://github.com/memi-design/audit-frontend-design) — inspect interface risks before changing UI.
-- [`remember-design-system`](https://github.com/memi-design/remember-design-system) — load compact product-system context.
-- [`enforce-design-ci`](https://github.com/memi-design/enforce-design-ci) — gate pull requests with deterministic evidence.
+## Design workflows
-Install the smallest workflow needed:
+Install only the workflow you need from Memi Design Skills:
```bash
-npx skills add memi-design/memi --skill audit-frontend-design
+npx skills add memi-design/design-skills --skill better-ui
```
-## Labs and integration proofs
-
-- [`mermaid-jam`](https://github.com/memi-design/mermaid-jam) — local-only FigJam plugin for editable Mermaid and markdown diagrams.
-- [`ripple-image-transitions`](https://github.com/memi-design/ripple-image-transitions) — SwiftUI and Metal evaluation fork.
-- [`chatbot`](https://github.com/memi-design/chatbot) — shadcn chatbot integration proof with Memi design CI.
-
-Proof forks preserve upstream attribution and do not imply partnership.
-
-The official CLI and Studio Homebrew tap lives at
-[`homebrew-memi`](https://github.com/memi-design/homebrew-memi).
+Focused mirrors remain available for the audit, memory, and CI workflows. Their canonical definitions are governed in the Memi repositories and generated mirrors must declare their source of truth.
## How we build
-- Read-only inspection is the default.
+- Read-only inspection is the default for the CLI.
- Findings include confidence, provenance, and file evidence.
- Deterministic checks rerun before a result is called verified.
- Existing design systems remain the source of truth.
-- New workflow contributions land in skills before compatibility shims.
- Public integrations must be runnable, attributed, and maintained.
+- In-development surfaces are labeled before they are promoted.
-[Documentation](https://memoire.cv) · [npm](https://www.npmjs.com/package/@memi-design/cli) · [Discussions](https://github.com/memi-design/memi/discussions) · [Organization architecture](https://github.com/memi-design/.github/blob/main/ORG_ARCHITECTURE.md)
+[Website](https://memoire.cv) · [Discussions](https://github.com/memi-design/memi/discussions) · [Organization architecture](https://github.com/memi-design/.github/blob/main/ORG_ARCHITECTURE.md) · [Brand manifest](https://github.com/memi-design/.github/blob/main/brand/brand-manifest.v1.json)
[Contribute](https://github.com/memi-design/.github/blob/main/CONTRIBUTING.md) · [Open-source model](https://github.com/memi-design/.github/blob/main/OPEN_SOURCE.md) · [Security](https://github.com/memi-design/.github/blob/main/SECURITY.md) · [Code of Conduct](https://github.com/memi-design/.github/blob/main/CODE_OF_CONDUCT.md)
diff --git a/scripts/lib/render-brand-documents.mjs b/scripts/lib/render-brand-documents.mjs
new file mode 100644
index 0000000..9c3a9a2
--- /dev/null
+++ b/scripts/lib/render-brand-documents.mjs
@@ -0,0 +1,254 @@
+const MANIFEST_PATH = "brand/brand-manifest.v1.json";
+
+function escapeCell(value) {
+ return String(value).replaceAll("|", "\\|").replaceAll("\n", " ");
+}
+
+function statusLabel(status) {
+ return status === "development" ? "In development" : "Available";
+}
+
+function markdownLink(label, url) {
+ return `[${escapeCell(label)}](${url})`;
+}
+
+function productLinks(product) {
+ const labels = {
+ repository: "Repository",
+ documentation: "Docs",
+ package: "npm",
+ download: "Download",
+ install: "Install",
+ };
+
+ return Object.entries(product.urls)
+ .map(([kind, url]) => markdownLink(labels[kind] ?? kind, url))
+ .join(" · ");
+}
+
+function renderProfile(manifest) {
+ const productRows = manifest.products.map(
+ (product) =>
+ `| ${markdownLink(product.name, product.urls.repository)} | ${statusLabel(product.status)} | ${escapeCell(product.role)} | ${productLinks(product)} |`,
+ );
+ const canvas = manifest.products.find((product) => product.id === "canvas");
+
+ return `
+
+
+
+
+
+
+
+
+
+# ${manifest.organization.name}
+
+${manifest.organization.tagline}
+
+Memi gives coding agents file-anchored design evidence, governed design workflows, a supervised native workbench, and an emerging local-first canvas.
+
+## Start with the CLI
+
+Run a read-only audit in any frontend repository:
+
+\`\`\`bash
+npx -y @memi-design/cli@latest diagnose . --json --no-write --fail-on none
+\`\`\`
+
+No account, API key, Figma file, global install, or daemon is required for the first audit.
+
+## Products
+
+| Product | Status | Role | Public surfaces |
+| --- | --- | --- | --- |
+${productRows.join("\n")}
+
+**Canvas boundary:** ${canvas.statusNote} Its current tests and deterministic demo evidence are engineering proof, not a claim of production readiness.
+
+## Design workflows
+
+Install only the workflow you need from Memi Design Skills:
+
+\`\`\`bash
+npx skills add memi-design/design-skills --skill better-ui
+\`\`\`
+
+Focused mirrors remain available for the audit, memory, and CI workflows. Their canonical definitions are governed in the Memi repositories and generated mirrors must declare their source of truth.
+
+## How we build
+
+- Read-only inspection is the default for the CLI.
+- Findings include confidence, provenance, and file evidence.
+- Deterministic checks rerun before a result is called verified.
+- Existing design systems remain the source of truth.
+- Public integrations must be runnable, attributed, and maintained.
+- In-development surfaces are labeled before they are promoted.
+
+[Website](${manifest.organization.urls.website}) · [Discussions](https://github.com/memi-design/memi/discussions) · [Organization architecture](https://github.com/memi-design/.github/blob/main/ORG_ARCHITECTURE.md) · [Brand manifest](https://github.com/memi-design/.github/blob/main/brand/brand-manifest.v1.json)
+
+[Contribute](https://github.com/memi-design/.github/blob/main/CONTRIBUTING.md) · [Open-source model](https://github.com/memi-design/.github/blob/main/OPEN_SOURCE.md) · [Security](https://github.com/memi-design/.github/blob/main/SECURITY.md) · [Code of Conduct](https://github.com/memi-design/.github/blob/main/CODE_OF_CONDUCT.md)
+`;
+}
+
+function renderArchitecture(manifest) {
+ const rows = manifest.products.map((product) => {
+ const future = product.license.futureLicense
+ ? `; ${product.license.futureLicense.spdx} on ${product.license.futureLicense.effectiveDate}`
+ : "";
+ return `| \`${product.id}\` | ${markdownLink(product.name, product.urls.repository)} | ${statusLabel(product.status)} | ${escapeCell(product.role)} | ${markdownLink(product.license.spdx, product.license.url)}${future} |`;
+ });
+ const canvas = manifest.products.find((product) => product.id === "canvas");
+
+ return `# Memi Organization Architecture
+
+This document defines the supported product surfaces in \`memi-design\`, their release boundaries, and the proof required before a repository is presented as official.
+
+The canonical machine-readable source is [\`${MANIFEST_PATH}\`](${MANIFEST_PATH}). This page is generated from brand revision **${manifest.brandRevision}**; run \`npm run brand:sync\` after changing the manifest.
+
+## Product surfaces
+
+| Product ID | Product | Status | Responsibility | License |
+| --- | --- | --- | --- | --- |
+${rows.join("\n")}
+
+### Canvas release boundary
+
+${canvas.statusNote} Canvas must remain labeled **In development** until its repository's capture, provider, source-write, security, recovery, and release gates are satisfied.
+
+## Distribution surfaces
+
+- \`homebrew-memi\` owns the canonical Homebrew formula and cask tap.
+- Focused skill repositories are install and discovery mirrors; they must identify their canonical source and remain synchronized.
+- The organization profile and [public website](${manifest.organization.urls.website}) are projections of the brand and release manifests, not independent version authorities.
+
+No personal namespace is an operational source, install, support, container, or release route.
+
+## Labs and integration proofs
+
+Labs demonstrate one bounded integration or design-engineering capability. They are not separate product lines and must preserve upstream attribution. A proof becomes official only when its README states the proof contract, the public path is runnable, and current verification evidence exists.
+
+## Repository contract
+
+Every official public repository must have:
+
+1. A one-sentence job and one first-run path.
+2. An explicit license and retained third-party attribution.
+3. A maintained README whose product identity matches the brand manifest.
+4. CI appropriate to its runtime and a pinned dependency policy.
+5. Security reporting through the organization policy.
+6. Topics, description, homepage, and repository visibility set deliberately.
+7. No copied upstream code or assets outside compatible license terms.
+8. A clear source-of-truth declaration when the repository is generated.
+
+## Release ownership
+
+| Surface | Source of truth | Identity constraint |
+| --- | --- | --- |
+| npm package | \`memi/release-manifest.json\` | Trusted Publisher targets \`memi-design/memi\` |
+| GitHub Action | \`memi/action.yml\` | Consumers pin a full commit SHA |
+| MCP Registry | \`memi/server.json\` | Current server identity remains compatible during migration |
+| Container images | Core release workflow | New releases publish only to the organization namespace |
+| Homebrew | \`homebrew-memi\` | The canonical tap is owned by \`memi-design\` |
+| Product identity | \`${MANIFEST_PATH}\` | Names, statuses, URLs, licenses, icons, and aliases use one brand revision |
+
+Release versions and public parity evidence stay in the core release manifest. A published artifact is not described as parity-verified until its independent verification gate passes.
+
+## Transfer gate
+
+Before moving a repository:
+
+- inventory releases, Actions, environments, Pages, packages, webhooks, deploy keys, and branch protections;
+- identify hard-coded owner paths and external trusted-publisher subjects;
+- preserve a redirect-compatible transition window;
+- update the canonical local remote;
+- rerun clean installs and public-link checks after the move.
+
+Any repository with a live release or Pages environment moves only after its external identity is ready. Historical personal namespaces may remain only inside the non-operational provenance allowlist.
+
+## Lifecycle
+
+- **Available:** supported now through at least one documented public route.
+- **Development:** implementation is public, but required product or release proof remains incomplete.
+- **Proof:** maintained integration with reproducible evidence.
+- **Archived:** read-only historical reference with a replacement or end-of-life notice.
+
+Repository count is not a growth metric. A repository belongs in the organization only when it makes a supported product easier to understand, install, verify, or extend.
+`;
+}
+
+function renderBrandReadme(manifest) {
+ const productRows = manifest.products.map((product) => {
+ const aliases = product.aliases.map((alias) => `\`${escapeCell(alias)}\``).join(", ");
+ const icon = product.icons[0];
+ return `| \`${product.id}\` | ${markdownLink(product.name, product.urls.repository)} | ${statusLabel(product.status)} | ${markdownLink(product.license.spdx, product.license.url)} | ${aliases} | ${markdownLink(icon.id, icon.url)} |`;
+ });
+ const allowlistRows = manifest.legacyProvenanceAllowlist.map(
+ (entry) =>
+ `| \`${entry.id}\` | ${escapeCell(entry.label)} | \`${entry.kind}\` | ${entry.permittedContexts.map((context) => `\`${context}\``).join(", ")} | ${escapeCell(entry.reason)} |`,
+ );
+
+ return `# Memi Brand Assets and Manifest
+
+This directory contains the canonical organization assets and the versioned product identity contract for Memi.
+
+## Sources of truth
+
+- [\`brand-manifest.v1.json\`](brand-manifest.v1.json) records brand revision **${manifest.brandRevision}** and the canonical product IDs, names, roles, statuses, URLs, licenses, icons, aliases, and legacy exceptions.
+- [\`brand-manifest.v1.schema.json\`](brand-manifest.v1.schema.json) is the JSON Schema for manifest version 1.
+- [Memi's public website](${manifest.organization.urls.website}) is a current organization surface; its domain is not a legacy alias.
+- \`npm run brand:check\` validates the schema, policy invariants, and synchronized documentation.
+- \`npm run brand:sync\` regenerates the organization profile and architecture documents after an intentional manifest edit.
+
+Consumers should reject unsupported \`schemaVersion\` values. Increment \`brandRevision\` for every identity change that downstream repositories must adopt.
+
+## Product registry
+
+| Product ID | Canonical name | Status | License | Accepted aliases | Primary icon |
+| --- | --- | --- | --- | --- | --- |
+${productRows.join("\n")}
+
+Aliases exist for search, migration, and compatibility. They do not replace the canonical name on current release, install, support, or documentation surfaces.
+
+## Legacy and provenance allowlist
+
+Legacy values are permitted only as **non-operational provenance**. They must never be used as a current source, install, download, support, package-publish, container-publish, or release destination. Exact machine-match values live only in the manifest so generated public documentation does not revive personal operational links.
+
+| Allowlist ID | Historical identity | Kind | Permitted contexts | Reason |
+| --- | --- | --- | --- | --- |
+${allowlistRows.join("\n")}
+
+Adding an entry requires a bounded context, a provenance reason, and \`operational: false\`. Prefer removing a legacy reference when immutable provenance does not require it.
+
+## Assets
+
+| Asset | Use | Size |
+| --- | --- | --- |
+| \`memi-avatar.png\` | GitHub organization avatar and square profile surfaces | 512 × 512 |
+| \`memi-social-preview.jpg\` | GitHub social previews | 1280 × 640 |
+| \`memi-brand-banner.png\` | Repository README, npm, and organization-profile banner | 1983 × 793 |
+
+## Usage
+
+- Keep the pixel-heart mark centered and uncropped.
+- Use the avatar on black or near-black surfaces.
+- Preserve the social preview's 2:1 composition.
+- Preserve the supplied banner's 2.5:1 composition and centered wordmark; do not crop, overlay text, or substitute a product alias.
+- Product-specific diagrams and screenshots may use their own visual language, but their product identity must match the manifest.
+
+## Provenance
+
+The source artwork was supplied by the project owner. The organization variants were produced for Memi by replacing or extending the original backgrounds with a near-black field while preserving the supplied pixel-mosaic forms. No third-party marks or assets are included.
+
+Copyright in the supplied artwork is retained by the project owner. Refer to [\`TRADEMARKS.md\`](TRADEMARKS.md) before reusing the Memi name or brand assets.
+`;
+}
+
+export function renderManagedDocuments(manifest) {
+ return new Map([
+ ["profile/README.md", renderProfile(manifest)],
+ ["ORG_ARCHITECTURE.md", renderArchitecture(manifest)],
+ ["brand/README.md", renderBrandReadme(manifest)],
+ ]);
+}
diff --git a/scripts/validate-brand-manifest.mjs b/scripts/validate-brand-manifest.mjs
new file mode 100644
index 0000000..3251b4a
--- /dev/null
+++ b/scripts/validate-brand-manifest.mjs
@@ -0,0 +1,252 @@
+import { readFile, writeFile } from "node:fs/promises";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+
+import Ajv2020 from "ajv/dist/2020.js";
+
+import { renderManagedDocuments } from "./lib/render-brand-documents.mjs";
+
+export const MANIFEST_RELATIVE_PATH = "brand/brand-manifest.v1.json";
+export const SCHEMA_RELATIVE_PATH = "brand/brand-manifest.v1.schema.json";
+
+const EXPECTED_PRODUCT_STATUSES = new Map([
+ ["cli", "available"],
+ ["studio", "available"],
+ ["design-skills", "available"],
+ ["canvas", "development"],
+]);
+
+const PERSONAL_OR_LEGACY_URL_PATTERNS = [
+ /https:\/\/github\.com\/sarveshsea(?:\/|$)/i,
+ /https:\/\/raw\.githubusercontent\.com\/sarveshsea(?:\/|$)/i,
+ /https:\/\/ghcr\.io\/sarveshsea(?:\/|$)/i,
+];
+
+const DOCUMENTATION_PATHS = [
+ "profile/README.md",
+ "ORG_ARCHITECTURE.md",
+ "brand/README.md",
+ "OPEN_SOURCE.md",
+ "CONTRIBUTING.md",
+ "GOVERNANCE.md",
+ "SECURITY.md",
+ "SUPPORT.md",
+ "CODE_OF_CONDUCT.md",
+];
+
+function formatAjvError(error) {
+ const location = error.instancePath || "/";
+ return `${location} ${error.message ?? "is invalid"}`;
+}
+
+export function validateManifestData(manifest, schema) {
+ const ajv = new Ajv2020({ allErrors: true, strict: true });
+ const validate = ajv.compile(schema);
+
+ return validate(manifest)
+ ? []
+ : (validate.errors ?? []).map(formatAjvError);
+}
+
+function validateProductContract(products) {
+ const errors = [];
+ const productsById = new Map(products.map((product) => [product.id, product]));
+
+ for (const [id, status] of EXPECTED_PRODUCT_STATUSES) {
+ const product = productsById.get(id);
+ if (!product) {
+ errors.push(`Missing canonical product ${id}.`);
+ } else if (product.status !== status) {
+ errors.push(`Product ${id} must have status ${status}.`);
+ }
+ }
+
+ for (const product of products) {
+ if (!EXPECTED_PRODUCT_STATUSES.has(product.id)) {
+ errors.push(`Unexpected canonical product ${product.id}.`);
+ }
+ }
+
+ return errors;
+}
+
+function validateAliases(products) {
+ const errors = [];
+ const aliases = new Map();
+
+ for (const product of products) {
+ for (const alias of product.aliases ?? []) {
+ const normalizedAlias = alias.normalize("NFKC").toLocaleLowerCase("en-US");
+ const owner = aliases.get(normalizedAlias);
+ if (owner && owner !== product.id) {
+ errors.push(`Alias ${alias} collides between ${owner} and ${product.id}.`);
+ } else {
+ aliases.set(normalizedAlias, product.id);
+ }
+ }
+ }
+
+ return errors;
+}
+
+function operationalUrls(product) {
+ return [
+ ...Object.values(product.urls ?? {}),
+ product.license?.url,
+ product.license?.futureLicense?.url,
+ ...(product.icons ?? []).map((icon) => icon.url),
+ ].filter(Boolean);
+}
+
+function validateOperationalUrls(products, organization) {
+ const errors = [];
+ const surfaces = [
+ {
+ label: "Organization",
+ urls: Object.values(organization?.urls ?? {}),
+ },
+ ...products.map((product) => ({
+ label: `Product ${product.id}`,
+ urls: operationalUrls(product),
+ })),
+ ];
+
+ for (const surface of surfaces) {
+ for (const url of surface.urls) {
+ if (PERSONAL_OR_LEGACY_URL_PATTERNS.some((pattern) => pattern.test(url))) {
+ errors.push(`${surface.label} uses personal or legacy URL ${url}.`);
+ }
+ }
+ }
+
+ return errors;
+}
+
+function validateAllowlist(entries) {
+ const errors = [];
+ const ids = new Set();
+ const values = new Set();
+
+ for (const entry of entries) {
+ if (ids.has(entry.id)) {
+ errors.push(`Legacy allowlist id ${entry.id} is duplicated.`);
+ }
+ if (values.has(entry.value)) {
+ errors.push(`Legacy allowlist value ${entry.value} is duplicated.`);
+ }
+ if (entry.operational !== false) {
+ errors.push(`Legacy allowlist entry ${entry.id} must be non-operational.`);
+ }
+ ids.add(entry.id);
+ values.add(entry.value);
+ }
+
+ return errors;
+}
+
+export function validateBrandPolicy(manifest) {
+ const products = Array.isArray(manifest.products) ? manifest.products : [];
+ const allowlist = Array.isArray(manifest.legacyProvenanceAllowlist)
+ ? manifest.legacyProvenanceAllowlist
+ : [];
+
+ return [
+ ...validateProductContract(products),
+ ...validateAliases(products),
+ ...validateOperationalUrls(products, manifest.organization),
+ ...validateAllowlist(allowlist),
+ ];
+}
+
+export { renderManagedDocuments };
+
+async function readJson(repositoryRoot, relativePath) {
+ return JSON.parse(
+ await readFile(path.join(repositoryRoot, relativePath), "utf8"),
+ );
+}
+
+async function validateDocumentationUrls(repositoryRoot) {
+ const errors = [];
+
+ for (const relativePath of DOCUMENTATION_PATHS) {
+ const content = await readFile(path.join(repositoryRoot, relativePath), "utf8");
+ if (PERSONAL_OR_LEGACY_URL_PATTERNS.some((pattern) => pattern.test(content))) {
+ errors.push(`${relativePath} contains a personal operational URL.`);
+ }
+ }
+
+ return errors;
+}
+
+export async function checkRepository(repositoryRoot) {
+ const [manifest, schema] = await Promise.all([
+ readJson(repositoryRoot, MANIFEST_RELATIVE_PATH),
+ readJson(repositoryRoot, SCHEMA_RELATIVE_PATH),
+ ]);
+ const errors = [
+ ...validateManifestData(manifest, schema),
+ ...validateBrandPolicy(manifest),
+ ];
+
+ for (const [relativePath, expectedContent] of renderManagedDocuments(manifest)) {
+ const actualContent = await readFile(path.join(repositoryRoot, relativePath), "utf8");
+ if (actualContent !== expectedContent) {
+ errors.push(`${relativePath} is not synchronized; run npm run brand:sync.`);
+ }
+ }
+
+ errors.push(...(await validateDocumentationUrls(repositoryRoot)));
+ return errors;
+}
+
+async function synchronizeDocuments(repositoryRoot, manifest) {
+ for (const [relativePath, content] of renderManagedDocuments(manifest)) {
+ await writeFile(path.join(repositoryRoot, relativePath), content, "utf8");
+ }
+}
+
+function repositoryRootFromScript() {
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
+}
+
+async function runCli() {
+ const repositoryRoot = repositoryRootFromScript();
+ const argument = process.argv[2] ?? "--check";
+
+ if (!["--check", "--write"].includes(argument) || process.argv.length > 3) {
+ console.error("Usage: node scripts/validate-brand-manifest.mjs [--check|--write]");
+ process.exitCode = 2;
+ return;
+ }
+
+ if (argument === "--write") {
+ const [manifest, schema] = await Promise.all([
+ readJson(repositoryRoot, MANIFEST_RELATIVE_PATH),
+ readJson(repositoryRoot, SCHEMA_RELATIVE_PATH),
+ ]);
+ const errors = [
+ ...validateManifestData(manifest, schema),
+ ...validateBrandPolicy(manifest),
+ ];
+ if (errors.length > 0) {
+ throw new Error(errors.join("\n"));
+ }
+ await synchronizeDocuments(repositoryRoot, manifest);
+ }
+
+ const errors = await checkRepository(repositoryRoot);
+ if (errors.length > 0) {
+ throw new Error(errors.join("\n"));
+ }
+
+ console.log("Brand manifest is valid and synchronized.");
+}
+
+const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : "";
+if (invokedPath === fileURLToPath(import.meta.url)) {
+ runCli().catch((error) => {
+ console.error(`Brand manifest validation failed:\n${error.message}`);
+ process.exitCode = 1;
+ });
+}
diff --git a/tests/brand-manifest.test.mjs b/tests/brand-manifest.test.mjs
index 338d654..a1507fd 100644
--- a/tests/brand-manifest.test.mjs
+++ b/tests/brand-manifest.test.mjs
@@ -57,6 +57,7 @@ test("manifest names the four canonical products and keeps Canvas in development
});
assert.equal(Number.isInteger(manifest.brandRevision), true);
assert.equal(manifest.brandRevision > 0, true);
+ assert.equal(manifest.organization.urls.website, "https://memoire.cv");
});
test("policy rejects missing, unexpected, and incorrectly staged products", async () => {
@@ -126,11 +127,11 @@ test("policy rejects personal namespaces in operational product URLs", async ()
);
});
-test("policy rejects the legacy website as an operational product URL", async () => {
+test("policy rejects personal namespaces in organization URLs", async () => {
const manifest = await readJson(MANIFEST_RELATIVE_PATH);
const invalidManifest = structuredClone(manifest);
- invalidManifest.products[0].urls.documentation =
- "https://memoire.cv/docs";
+ invalidManifest.organization.urls.github =
+ "https://github.com/sarveshsea";
assert.match(
validateBrandPolicy(invalidManifest).join("\n"),
@@ -217,7 +218,6 @@ test("checked-in docs avoid stale pins and personal operational URLs", async ()
assert.doesNotMatch(combined, /@memi-design\/cli@\d+\.\d+\.\d+/);
assert.doesNotMatch(combined, /https:\/\/github\.com\/sarveshsea\//);
- assert.doesNotMatch(combined, /https:\/\/(?:www\.)?memoire\.cv\b/);
assert.match(combined, /non-operational provenance/i);
});
From bf0c495750998e179c9dda383db5cf4c5e5cbd8a Mon Sep 17 00:00:00 2001
From: sarveshsea
Date: Sun, 2 Aug 2026 13:25:32 -0500
Subject: [PATCH 4/8] test: define icon and lowercase brand truth
---
tests/brand-manifest.test.mjs | 39 +++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/tests/brand-manifest.test.mjs b/tests/brand-manifest.test.mjs
index a1507fd..05aaf87 100644
--- a/tests/brand-manifest.test.mjs
+++ b/tests/brand-manifest.test.mjs
@@ -60,6 +60,45 @@ test("manifest names the four canonical products and keeps Canvas in development
assert.equal(manifest.organization.urls.website, "https://memoire.cv");
});
+test("manifest enforces lowercase memi naming and content-addressed product icons", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const products = Object.fromEntries(
+ manifest.products.map((product) => [product.id, product]),
+ );
+
+ assert.equal(manifest.organization.name, "memi");
+ assert.deepEqual(
+ manifest.products.map(({ name }) => name),
+ ["memi CLI", "memi Studio", "memi Design Skills", "memi Canvas"],
+ );
+ for (const product of manifest.products) {
+ for (const icon of product.icons) {
+ assert.match(icon.sha256, /^[a-f0-9]{64}$/);
+ }
+ }
+
+ assert.equal(products.canvas.icons[0].id, "canvas-single-heart");
+ assert.equal(
+ products.canvas.icons[0].sha256,
+ "da068f20ba9e0e43f59ebde8602b43342f8c77fef2c080155a18d5a8fd0e25c2",
+ );
+ assert.match(products.canvas.icons[0].url, /memi-canvas\/.*\/icon\.png$/);
+ assert.match(
+ products.canvas.icons[0].sourceUrl,
+ /MemiCanvas-Iteration-02\.icon\/icon\.json$/,
+ );
+});
+
+test("Design Skills install URL resolves to organization-owned instructions", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const designSkills = manifest.products.find(({ id }) => id === "design-skills");
+
+ assert.equal(
+ designSkills.urls.install,
+ "https://github.com/memi-design/design-skills#installation",
+ );
+});
+
test("policy rejects missing, unexpected, and incorrectly staged products", async () => {
const manifest = await readJson(MANIFEST_RELATIVE_PATH);
const invalidManifest = structuredClone(manifest);
From b9495124df38e8358ebe8f047918634c03365a11 Mon Sep 17 00:00:00 2001
From: sarveshsea
Date: Sun, 2 Aug 2026 13:26:12 -0500
Subject: [PATCH 5/8] fix: pin canonical icon and lowercase brand truth
---
ORG_ARCHITECTURE.md | 10 +++++-----
brand/README.md | 10 +++++-----
brand/brand-manifest.v1.json | 27 ++++++++++++++++-----------
brand/brand-manifest.v1.schema.json | 4 +++-
profile/README.md | 10 +++++-----
5 files changed, 34 insertions(+), 27 deletions(-)
diff --git a/ORG_ARCHITECTURE.md b/ORG_ARCHITECTURE.md
index 61cb9af..60ae4bd 100644
--- a/ORG_ARCHITECTURE.md
+++ b/ORG_ARCHITECTURE.md
@@ -2,16 +2,16 @@
This document defines the supported product surfaces in `memi-design`, their release boundaries, and the proof required before a repository is presented as official.
-The canonical machine-readable source is [`brand/brand-manifest.v1.json`](brand/brand-manifest.v1.json). This page is generated from brand revision **1**; run `npm run brand:sync` after changing the manifest.
+The canonical machine-readable source is [`brand/brand-manifest.v1.json`](brand/brand-manifest.v1.json). This page is generated from brand revision **2**; run `npm run brand:sync` after changing the manifest.
## Product surfaces
| Product ID | Product | Status | Responsibility | License |
| --- | --- | --- | --- | --- |
-| `cli` | [Memi CLI](https://github.com/memi-design/memi) | Available | Read-only design engineering audit and skill layer for coding agents. | [MIT](https://github.com/memi-design/memi/blob/main/LICENSE) |
-| `studio` | [Memi Studio](https://github.com/memi-design/memi-studio) | Available | Native macOS companion for supervised agent workflows and artifact review. | [FSL-1.1-ALv2](https://github.com/memi-design/memi-studio/blob/main/LICENSE); Apache-2.0 on 2028-05-09 |
-| `design-skills` | [Memi Design Skills](https://github.com/memi-design/design-skills) | Available | Governed catalog of portable and capability-gated design workflows for coding agents. | [MIT](https://github.com/memi-design/design-skills/blob/main/LICENSE) |
-| `canvas` | [Memi Canvas](https://github.com/memi-design/memi-canvas) | In development | Local-first canvas workbench for understanding, creating, and verifying software interfaces. | [Apache-2.0](https://github.com/memi-design/memi-canvas/blob/main/LICENSE) |
+| `cli` | [memi CLI](https://github.com/memi-design/memi) | Available | Read-only design engineering audit and skill layer for coding agents. | [MIT](https://github.com/memi-design/memi/blob/main/LICENSE) |
+| `studio` | [memi Studio](https://github.com/memi-design/memi-studio) | Available | Native macOS companion for supervised agent workflows and artifact review. | [FSL-1.1-ALv2](https://github.com/memi-design/memi-studio/blob/main/LICENSE); Apache-2.0 on 2028-05-09 |
+| `design-skills` | [memi Design Skills](https://github.com/memi-design/design-skills) | Available | Governed catalog of portable and capability-gated design workflows for coding agents. | [MIT](https://github.com/memi-design/design-skills/blob/main/LICENSE) |
+| `canvas` | [memi Canvas](https://github.com/memi-design/memi-canvas) | In development | Local-first canvas workbench for understanding, creating, and verifying software interfaces. | [Apache-2.0](https://github.com/memi-design/memi-canvas/blob/main/LICENSE) |
### Canvas release boundary
diff --git a/brand/README.md b/brand/README.md
index 4a06e3c..19c18a5 100644
--- a/brand/README.md
+++ b/brand/README.md
@@ -4,7 +4,7 @@ This directory contains the canonical organization assets and the versioned prod
## Sources of truth
-- [`brand-manifest.v1.json`](brand-manifest.v1.json) records brand revision **1** and the canonical product IDs, names, roles, statuses, URLs, licenses, icons, aliases, and legacy exceptions.
+- [`brand-manifest.v1.json`](brand-manifest.v1.json) records brand revision **2** and the canonical product IDs, names, roles, statuses, URLs, licenses, icons, aliases, and legacy exceptions.
- [`brand-manifest.v1.schema.json`](brand-manifest.v1.schema.json) is the JSON Schema for manifest version 1.
- [Memi's public website](https://memoire.cv) is a current organization surface; its domain is not a legacy alias.
- `npm run brand:check` validates the schema, policy invariants, and synchronized documentation.
@@ -16,10 +16,10 @@ Consumers should reject unsupported `schemaVersion` values. Increment `brandRevi
| Product ID | Canonical name | Status | License | Accepted aliases | Primary icon |
| --- | --- | --- | --- | --- | --- |
-| `cli` | [Memi CLI](https://github.com/memi-design/memi) | Available | [MIT](https://github.com/memi-design/memi/blob/main/LICENSE) | `Memi`, `Memi Engine`, `Mémoire`, `Mémoire CLI`, `Mémoire Engine` | [memi-mark](https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png) |
-| `studio` | [Memi Studio](https://github.com/memi-design/memi-studio) | Available | [FSL-1.1-ALv2](https://github.com/memi-design/memi-studio/blob/main/LICENSE) | `Mémoire Studio` | [studio-app-icon](https://raw.githubusercontent.com/memi-design/memi-studio/main/docs/assets/memi-icon-dark.png) |
-| `design-skills` | [Memi Design Skills](https://github.com/memi-design/design-skills) | Available | [MIT](https://github.com/memi-design/design-skills/blob/main/LICENSE) | `Design Skills`, `Memi Skills`, `Mémoire Design Skills` | [memi-mark](https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png) |
-| `canvas` | [Memi Canvas](https://github.com/memi-design/memi-canvas) | In development | [Apache-2.0](https://github.com/memi-design/memi-canvas/blob/main/LICENSE) | `Mémoire Canvas` | [memi-mark](https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png) |
+| `cli` | [memi CLI](https://github.com/memi-design/memi) | Available | [MIT](https://github.com/memi-design/memi/blob/main/LICENSE) | `Memi`, `Memi Engine`, `Mémoire`, `Mémoire CLI`, `Mémoire Engine` | [memi-mark](https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png) |
+| `studio` | [memi Studio](https://github.com/memi-design/memi-studio) | Available | [FSL-1.1-ALv2](https://github.com/memi-design/memi-studio/blob/main/LICENSE) | `Mémoire Studio` | [studio-app-icon](https://raw.githubusercontent.com/memi-design/memi-studio/main/docs/assets/memi-icon-dark.png) |
+| `design-skills` | [memi Design Skills](https://github.com/memi-design/design-skills) | Available | [MIT](https://github.com/memi-design/design-skills/blob/main/LICENSE) | `Design Skills`, `Memi Skills`, `Mémoire Design Skills` | [memi-mark](https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png) |
+| `canvas` | [memi Canvas](https://github.com/memi-design/memi-canvas) | In development | [Apache-2.0](https://github.com/memi-design/memi-canvas/blob/main/LICENSE) | `Mémoire Canvas` | [canvas-single-heart](https://raw.githubusercontent.com/memi-design/memi-canvas/main/apps/macos/src-tauri/icons/icon.png) |
Aliases exist for search, migration, and compatibility. They do not replace the canonical name on current release, install, support, or documentation surfaces.
diff --git a/brand/brand-manifest.v1.json b/brand/brand-manifest.v1.json
index 26174b0..41e87a1 100644
--- a/brand/brand-manifest.v1.json
+++ b/brand/brand-manifest.v1.json
@@ -1,11 +1,11 @@
{
"$schema": "./brand-manifest.v1.schema.json",
"schemaVersion": 1,
- "brandRevision": 1,
+ "brandRevision": 2,
"updatedAt": "2026-08-02",
"organization": {
"id": "memi-design",
- "name": "Memi",
+ "name": "memi",
"tagline": "The design layer for agentic AI.",
"urls": {
"github": "https://github.com/memi-design",
@@ -15,7 +15,7 @@
"products": [
{
"id": "cli",
- "name": "Memi CLI",
+ "name": "memi CLI",
"role": "Read-only design engineering audit and skill layer for coding agents.",
"status": "available",
"urls": {
@@ -33,6 +33,7 @@
"id": "memi-mark",
"purpose": "primary",
"url": "https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png",
+ "sha256": "64b988527b6e5dd8a5d4ad13166aa944b8522f5adf8264d115aab0e4bc54ecad",
"alt": "Memi pixel-heart mark"
}
],
@@ -46,7 +47,7 @@
},
{
"id": "studio",
- "name": "Memi Studio",
+ "name": "memi Studio",
"role": "Native macOS companion for supervised agent workflows and artifact review.",
"status": "available",
"urls": {
@@ -69,6 +70,7 @@
"id": "studio-app-icon",
"purpose": "app",
"url": "https://raw.githubusercontent.com/memi-design/memi-studio/main/docs/assets/memi-icon-dark.png",
+ "sha256": "87cd2c6467ab58387d7eb2597ee2d56605cb89f1e7380d874895d63a890de5c8",
"alt": "Memi Studio app icon"
}
],
@@ -78,13 +80,13 @@
},
{
"id": "design-skills",
- "name": "Memi Design Skills",
+ "name": "memi Design Skills",
"role": "Governed catalog of portable and capability-gated design workflows for coding agents.",
"status": "available",
"urls": {
"repository": "https://github.com/memi-design/design-skills",
"documentation": "https://github.com/memi-design/design-skills#readme",
- "install": "https://skills.sh/memi-design/design-skills"
+ "install": "https://github.com/memi-design/design-skills#installation"
},
"license": {
"spdx": "MIT",
@@ -96,6 +98,7 @@
"id": "memi-mark",
"purpose": "primary",
"url": "https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png",
+ "sha256": "64b988527b6e5dd8a5d4ad13166aa944b8522f5adf8264d115aab0e4bc54ecad",
"alt": "Memi pixel-heart mark"
}
],
@@ -107,7 +110,7 @@
},
{
"id": "canvas",
- "name": "Memi Canvas",
+ "name": "memi Canvas",
"role": "Local-first canvas workbench for understanding, creating, and verifying software interfaces.",
"status": "development",
"statusNote": "Open-source M0 development snapshot; not yet a production importer or source editor.",
@@ -122,10 +125,12 @@
},
"icons": [
{
- "id": "memi-mark",
- "purpose": "primary",
- "url": "https://raw.githubusercontent.com/memi-design/.github/main/brand/memi-avatar.png",
- "alt": "Memi pixel-heart mark"
+ "id": "canvas-single-heart",
+ "purpose": "app",
+ "url": "https://raw.githubusercontent.com/memi-design/memi-canvas/main/apps/macos/src-tauri/icons/icon.png",
+ "sourceUrl": "https://raw.githubusercontent.com/memi-design/memi-canvas/main/apps/macos/src-tauri/icons/source/MemiCanvas-Iteration-02.icon/icon.json",
+ "sha256": "da068f20ba9e0e43f59ebde8602b43342f8c77fef2c080155a18d5a8fd0e25c2",
+ "alt": "Ruby single pixel-heart memi Canvas icon"
}
],
"aliases": [
diff --git a/brand/brand-manifest.v1.schema.json b/brand/brand-manifest.v1.schema.json
index 71d1c1d..da93815 100644
--- a/brand/brand-manifest.v1.schema.json
+++ b/brand/brand-manifest.v1.schema.json
@@ -120,11 +120,13 @@
"icon": {
"type": "object",
"additionalProperties": false,
- "required": ["id", "purpose", "url", "alt"],
+ "required": ["id", "purpose", "url", "sha256", "alt"],
"properties": {
"id": { "$ref": "#/$defs/slug" },
"purpose": { "enum": ["primary", "app", "mark"] },
"url": { "$ref": "#/$defs/httpsUrl" },
+ "sourceUrl": { "$ref": "#/$defs/httpsUrl" },
+ "sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
"alt": { "type": "string", "minLength": 1 }
}
},
diff --git a/profile/README.md b/profile/README.md
index 10373b7..51c3936 100644
--- a/profile/README.md
+++ b/profile/README.md
@@ -8,7 +8,7 @@
-# Memi
+# memi
The design layer for agentic AI.
@@ -28,10 +28,10 @@ No account, API key, Figma file, global install, or daemon is required for the f
| Product | Status | Role | Public surfaces |
| --- | --- | --- | --- |
-| [Memi CLI](https://github.com/memi-design/memi) | Available | Read-only design engineering audit and skill layer for coding agents. | [Repository](https://github.com/memi-design/memi) · [Docs](https://github.com/memi-design/memi/blob/main/docs/README.md) · [npm](https://www.npmjs.com/package/@memi-design/cli) |
-| [Memi Studio](https://github.com/memi-design/memi-studio) | Available | Native macOS companion for supervised agent workflows and artifact review. | [Repository](https://github.com/memi-design/memi-studio) · [Docs](https://github.com/memi-design/memi-studio#readme) · [Download](https://github.com/memi-design/memi-studio/releases/latest) |
-| [Memi Design Skills](https://github.com/memi-design/design-skills) | Available | Governed catalog of portable and capability-gated design workflows for coding agents. | [Repository](https://github.com/memi-design/design-skills) · [Docs](https://github.com/memi-design/design-skills#readme) · [Install](https://skills.sh/memi-design/design-skills) |
-| [Memi Canvas](https://github.com/memi-design/memi-canvas) | In development | Local-first canvas workbench for understanding, creating, and verifying software interfaces. | [Repository](https://github.com/memi-design/memi-canvas) · [Docs](https://github.com/memi-design/memi-canvas#readme) |
+| [memi CLI](https://github.com/memi-design/memi) | Available | Read-only design engineering audit and skill layer for coding agents. | [Repository](https://github.com/memi-design/memi) · [Docs](https://github.com/memi-design/memi/blob/main/docs/README.md) · [npm](https://www.npmjs.com/package/@memi-design/cli) |
+| [memi Studio](https://github.com/memi-design/memi-studio) | Available | Native macOS companion for supervised agent workflows and artifact review. | [Repository](https://github.com/memi-design/memi-studio) · [Docs](https://github.com/memi-design/memi-studio#readme) · [Download](https://github.com/memi-design/memi-studio/releases/latest) |
+| [memi Design Skills](https://github.com/memi-design/design-skills) | Available | Governed catalog of portable and capability-gated design workflows for coding agents. | [Repository](https://github.com/memi-design/design-skills) · [Docs](https://github.com/memi-design/design-skills#readme) · [Install](https://github.com/memi-design/design-skills#installation) |
+| [memi Canvas](https://github.com/memi-design/memi-canvas) | In development | Local-first canvas workbench for understanding, creating, and verifying software interfaces. | [Repository](https://github.com/memi-design/memi-canvas) · [Docs](https://github.com/memi-design/memi-canvas#readme) |
**Canvas boundary:** Open-source M0 development snapshot; not yet a production importer or source editor. Its current tests and deterministic demo evidence are engineering proof, not a claim of production readiness.
From 4adcf431364e988a793c4e921393be6e12a25d53 Mon Sep 17 00:00:00 2001
From: sarveshsea
Date: Sun, 2 Aug 2026 13:31:19 -0500
Subject: [PATCH 6/8] test: define product package identities
---
tests/brand-manifest.test.mjs | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/tests/brand-manifest.test.mjs b/tests/brand-manifest.test.mjs
index 05aaf87..f20d1a8 100644
--- a/tests/brand-manifest.test.mjs
+++ b/tests/brand-manifest.test.mjs
@@ -99,6 +99,33 @@ test("Design Skills install URL resolves to organization-owned instructions", as
);
});
+test("manifest records current and compatibility package identities explicitly", async () => {
+ const manifest = await readJson(MANIFEST_RELATIVE_PATH);
+ const products = Object.fromEntries(
+ manifest.products.map((product) => [product.id, product]),
+ );
+
+ assert.deepEqual(products.cli.packages, [
+ {
+ name: "@memi-design/cli",
+ registry: "npm",
+ status: "current",
+ url: "https://www.npmjs.com/package/@memi-design/cli",
+ },
+ ]);
+ assert.deepEqual(products["design-skills"].packages, [
+ {
+ name: "@memoire/design-skills",
+ registry: "workspace",
+ status: "legacy-compatibility",
+ url: "https://github.com/memi-design/design-skills",
+ note: "Repository tooling identifier only; not a public npm installation surface.",
+ },
+ ]);
+ assert.deepEqual(products.studio.packages, []);
+ assert.deepEqual(products.canvas.packages, []);
+});
+
test("policy rejects missing, unexpected, and incorrectly staged products", async () => {
const manifest = await readJson(MANIFEST_RELATIVE_PATH);
const invalidManifest = structuredClone(manifest);
From ac3d9c13237c8dfe1b80db9080a0786bef38941e Mon Sep 17 00:00:00 2001
From: sarveshsea
Date: Sun, 2 Aug 2026 13:32:26 -0500
Subject: [PATCH 7/8] feat: encode canonical package identities
---
ORG_ARCHITECTURE.md | 2 +-
brand/README.md | 2 +-
brand/brand-manifest.v1.json | 21 ++++++++++++++++++++-
brand/brand-manifest.v1.schema.json | 18 +++++++++++++++++-
scripts/validate-brand-manifest.mjs | 1 +
tests/brand-manifest.test.mjs | 8 ++++++++
6 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/ORG_ARCHITECTURE.md b/ORG_ARCHITECTURE.md
index 60ae4bd..dfe9c67 100644
--- a/ORG_ARCHITECTURE.md
+++ b/ORG_ARCHITECTURE.md
@@ -2,7 +2,7 @@
This document defines the supported product surfaces in `memi-design`, their release boundaries, and the proof required before a repository is presented as official.
-The canonical machine-readable source is [`brand/brand-manifest.v1.json`](brand/brand-manifest.v1.json). This page is generated from brand revision **2**; run `npm run brand:sync` after changing the manifest.
+The canonical machine-readable source is [`brand/brand-manifest.v1.json`](brand/brand-manifest.v1.json). This page is generated from brand revision **3**; run `npm run brand:sync` after changing the manifest.
## Product surfaces
diff --git a/brand/README.md b/brand/README.md
index 19c18a5..43a8fb8 100644
--- a/brand/README.md
+++ b/brand/README.md
@@ -4,7 +4,7 @@ This directory contains the canonical organization assets and the versioned prod
## Sources of truth
-- [`brand-manifest.v1.json`](brand-manifest.v1.json) records brand revision **2** and the canonical product IDs, names, roles, statuses, URLs, licenses, icons, aliases, and legacy exceptions.
+- [`brand-manifest.v1.json`](brand-manifest.v1.json) records brand revision **3** and the canonical product IDs, names, roles, statuses, URLs, licenses, icons, aliases, and legacy exceptions.
- [`brand-manifest.v1.schema.json`](brand-manifest.v1.schema.json) is the JSON Schema for manifest version 1.
- [Memi's public website](https://memoire.cv) is a current organization surface; its domain is not a legacy alias.
- `npm run brand:check` validates the schema, policy invariants, and synchronized documentation.
diff --git a/brand/brand-manifest.v1.json b/brand/brand-manifest.v1.json
index 41e87a1..ae5b7ec 100644
--- a/brand/brand-manifest.v1.json
+++ b/brand/brand-manifest.v1.json
@@ -1,7 +1,7 @@
{
"$schema": "./brand-manifest.v1.schema.json",
"schemaVersion": 1,
- "brandRevision": 2,
+ "brandRevision": 3,
"updatedAt": "2026-08-02",
"organization": {
"id": "memi-design",
@@ -23,6 +23,14 @@
"documentation": "https://github.com/memi-design/memi/blob/main/docs/README.md",
"package": "https://www.npmjs.com/package/@memi-design/cli"
},
+ "packages": [
+ {
+ "name": "@memi-design/cli",
+ "registry": "npm",
+ "status": "current",
+ "url": "https://www.npmjs.com/package/@memi-design/cli"
+ }
+ ],
"license": {
"spdx": "MIT",
"name": "MIT License",
@@ -55,6 +63,7 @@
"documentation": "https://github.com/memi-design/memi-studio#readme",
"download": "https://github.com/memi-design/memi-studio/releases/latest"
},
+ "packages": [],
"license": {
"spdx": "FSL-1.1-ALv2",
"name": "Functional Source License 1.1 with Apache-2.0 future license",
@@ -88,6 +97,15 @@
"documentation": "https://github.com/memi-design/design-skills#readme",
"install": "https://github.com/memi-design/design-skills#installation"
},
+ "packages": [
+ {
+ "name": "@memoire/design-skills",
+ "registry": "workspace",
+ "status": "legacy-compatibility",
+ "url": "https://github.com/memi-design/design-skills",
+ "note": "Repository tooling identifier only; not a public npm installation surface."
+ }
+ ],
"license": {
"spdx": "MIT",
"name": "MIT License",
@@ -118,6 +136,7 @@
"repository": "https://github.com/memi-design/memi-canvas",
"documentation": "https://github.com/memi-design/memi-canvas#readme"
},
+ "packages": [],
"license": {
"spdx": "Apache-2.0",
"name": "Apache License 2.0",
diff --git a/brand/brand-manifest.v1.schema.json b/brand/brand-manifest.v1.schema.json
index da93815..051e86f 100644
--- a/brand/brand-manifest.v1.schema.json
+++ b/brand/brand-manifest.v1.schema.json
@@ -62,7 +62,7 @@
}
}
],
- "required": ["id", "name", "role", "status", "urls", "license", "icons", "aliases"],
+ "required": ["id", "name", "role", "status", "urls", "packages", "license", "icons", "aliases"],
"properties": {
"id": { "$ref": "#/$defs/slug" },
"name": { "type": "string", "minLength": 1 },
@@ -70,6 +70,10 @@
"status": { "enum": ["available", "development"] },
"statusNote": { "type": "string", "minLength": 1 },
"urls": { "$ref": "#/$defs/productUrls" },
+ "packages": {
+ "type": "array",
+ "items": { "$ref": "#/$defs/packageIdentity" }
+ },
"license": { "$ref": "#/$defs/license" },
"icons": {
"type": "array",
@@ -96,6 +100,18 @@
"install": { "$ref": "#/$defs/httpsUrl" }
}
},
+ "packageIdentity": {
+ "type": "object",
+ "additionalProperties": false,
+ "required": ["name", "registry", "status", "url"],
+ "properties": {
+ "name": { "type": "string", "minLength": 1 },
+ "registry": { "enum": ["npm", "workspace"] },
+ "status": { "enum": ["current", "legacy-compatibility"] },
+ "url": { "$ref": "#/$defs/httpsUrl" },
+ "note": { "type": "string", "minLength": 1 }
+ }
+ },
"license": {
"type": "object",
"additionalProperties": false,
diff --git a/scripts/validate-brand-manifest.mjs b/scripts/validate-brand-manifest.mjs
index 3251b4a..97a5eea 100644
--- a/scripts/validate-brand-manifest.mjs
+++ b/scripts/validate-brand-manifest.mjs
@@ -92,6 +92,7 @@ function validateAliases(products) {
function operationalUrls(product) {
return [
...Object.values(product.urls ?? {}),
+ ...(product.packages ?? []).map((packageIdentity) => packageIdentity.url),
product.license?.url,
product.license?.futureLicense?.url,
...(product.icons ?? []).map((icon) => icon.url),
diff --git a/tests/brand-manifest.test.mjs b/tests/brand-manifest.test.mjs
index f20d1a8..0b7610f 100644
--- a/tests/brand-manifest.test.mjs
+++ b/tests/brand-manifest.test.mjs
@@ -191,6 +191,14 @@ test("policy rejects personal namespaces in operational product URLs", async ()
validateBrandPolicy(invalidManifest).join("\n"),
/personal or legacy URL/i,
);
+
+ const invalidPackageManifest = structuredClone(manifest);
+ invalidPackageManifest.products[0].packages[0].url =
+ "https://github.com/sarveshsea/memi";
+ assert.match(
+ validateBrandPolicy(invalidPackageManifest).join("\n"),
+ /personal or legacy URL/i,
+ );
});
test("policy rejects personal namespaces in organization URLs", async () => {
From aaa4b4bd5feac022f7935d5c447939a1f643fb01 Mon Sep 17 00:00:00 2001
From: sarveshsea
Date: Sun, 2 Aug 2026 13:58:53 -0500
Subject: [PATCH 8/8] chore: normalize organization ignore file
---
.gitignore | 1 -
1 file changed, 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index d570088..c2658d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1 @@
node_modules/
-