Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* text=auto eol=lf

*.tgz -text
*.zip -text
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
pull_request:

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
strategy:
fail-fast: false
matrix:
os:
- ubuntu-24.04
- windows-2022
runs-on: ${{ matrix.os }}
timeout-minutes: 20
steps:
- name: Check out source
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Install pnpm
uses: pnpm/action-setup@0977fd99725f1db4007ccb2928dbb4e90d06cc86 # v6.0.10
with:
version: 10.32.1

- name: Install Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .node-version
cache: pnpm

- name: Install exact dependencies
run: pnpm install --frozen-lockfile

- name: Audit high-severity advisories
run: pnpm audit --audit-level high

- name: Run the authoritative repository gate
run: pnpm check
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
# Changelog

All material protocol changes are recorded here. MASA uses semantic versioning for normative schemas and behavior.
All material protocol and reference-tooling changes are recorded here. MASA uses semantic versioning; a tooling patch may advance without changing the normative protocol version when its record contracts remain compatible.

## 0.1.1 - 2026-08-09

Patch release of the TypeScript reference implementation. The normative MASA protocol, schemas, capability-set format, profile directories, and record/request version fields remain `0.1.0`.

- Enforced every declared profile during public audits and recursively removed approved-extension secrets, credential-bearing URL parameters, absolute private paths, and nested precise coordinates.
- Expanded conservative offline non-public address detection across private, documentation, benchmarking, selected reserved IPv4/IPv6 space, and common transition forms; DNS resolution remains an explicitly documented connection-time policy boundary.
- Refused processing plans against invalid target records and removed duplicate MCP validation work.
- Made ZIP packing and promotion portable across Windows path and directory semantics, bounded temporary names independently of caller filenames, and added a Windows release-gate lane.
- Separated normative protocol identity from generated reference-implementation identity across the CLI, MCP server, capabilities, resources, and conformance evidence.
- Added deterministic capability metadata, synchronized release-version generation, pinned read-only CI, dependency maintenance, and a gate that validates the exact checked-in evidence set against the current specification, fixtures, runner, and release identity.

## 0.1.0 - 2026-08-07

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

**MASA** is a project-agnostic Sound Matter Aware protocol. It provides a local-first, language-neutral contract for systems that need to describe, listen to, measure, transform, granulate, dissect, generate, map, relate, govern, and exchange sound as matter without confusing an audio file, a physical event, a perceptual account, or a computational claim. Conformance never depends on any other repository.

Version `0.1.0` is the first public release, MIT-licensed and open to any project. Its normative sources are the specification, JSON Schemas, ontology registries, and conformance fixtures in this repository. The TypeScript packages, CLI, and MCP server are reference implementations of those artifacts.
Protocol version `0.1.0` is the first public specification, MIT-licensed and open to any project. Its normative sources are the specification, JSON Schemas, ontology registries, and conformance fixtures in this repository. The current TypeScript reference-tooling release is `0.1.1`; tooling patches do not rename or silently revise the normative `0.1.0` resources.

## What is included

Expand Down Expand Up @@ -49,7 +49,7 @@ See [`docs/project-agnostic-integration.md`](docs/project-agnostic-integration.m

## Local conformance evidence

The reference implementation records separate evidence for the `reader`, `writer`, `transformer`, `agent-host`, and `publisher` classes in [`conformance/0.1.0/evidence`](conformance/0.1.0/evidence). The current local run reports all five classes conformant on Node.js 22.22.3 for macOS arm64 against fixture-manifest digest `0240f5403d9d626c3eef75a55eb640cea84cf5b6d17d2824fe4874561c27be95`, computed over the examples, capability catalog, schemas, ontology registries, and JSON-LD context.
The reference implementation records separate evidence for the `reader`, `writer`, `transformer`, `agent-host`, and `publisher` classes in [`conformance/0.1.0/evidence`](conformance/0.1.0/evidence). The current local run reports all five classes conformant on Node.js 22.22.3 for macOS arm64 against fixture-manifest digest `7f57b4870c2414936114ce906258e1d4816be340d1c3c591cb95eec80bc9cdea`. The digest is refreshed from the examples, specification, capability catalog, schemas, ontology registries, JSON-LD context, and executable conformance runner whenever evidence is intentionally recorded.

Run `pnpm check` to regenerate derived code and verify conformance on the current machine. Run `pnpm conformance:evidence` only when intentionally recording a new local evidence snapshot. Conformance is always specific to an implementation version, MASA version, profile, class, platform, and exact fixture set; it is not a universal certification.

Expand Down
6 changes: 3 additions & 3 deletions capabilities/0.1.0/reference.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
"masaVersion": "0.1.0",
"id": "https://masa.sonicfield.org/capabilities/0.1.0/reference",
"implementation": {
"id": "https://masa.sonicfield.org/implementations/typescript-reference/0.1.0",
"id": "https://masa.sonicfield.org/implementations/typescript-reference/0.1.1",
"name": "MASA local TypeScript reference",
"version": "0.1.0"
"version": "0.1.1"
},
"generatedAt": "2026-07-27T00:00:00Z",
"generatedAt": "2026-08-09T00:00:00.000Z",
"capabilities": [
{
"id": "https://masa.sonicfield.org/capabilities/0.1.0/matter.validate",
Expand Down
4 changes: 2 additions & 2 deletions cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sonicfield/masa-cli",
"version": "0.1.0",
"version": "0.1.1",
"private": true,
"license": "MIT",
"description": "Local command-line reference implementation for MASA",
Expand Down Expand Up @@ -32,7 +32,7 @@
"@sonicfield/masa-validator": "workspace:*"
},
"devDependencies": {
"@types/node": "24.3.0",
"@types/node": "24.13.3",
"typescript": "7.0.2",
"vitest": "4.1.10"
},
Expand Down
22 changes: 21 additions & 1 deletion cli/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import {
MASA_PROTOCOL_VERSION,
MASA_REFERENCE_IMPLEMENTATION_VERSION,
} from "@sonicfield/masa";
import { afterEach, describe, expect, it } from "vitest";
import { runCli, type CliIo } from "./index.js";

Expand All @@ -26,7 +30,9 @@ describe("MASA CLI", () => {
it("prints help without side effects", async () => {
const result = capture();
await expect(runCli(["help"], result.io)).resolves.toBe(0);
expect(result.out.join("\n")).toContain("MASA 0.1.0 local CLI");
expect(result.out.join("\n")).toContain(
`MASA local CLI ${MASA_REFERENCE_IMPLEMENTATION_VERSION} (protocol ${MASA_PROTOCOL_VERSION})`,
);
expect(result.error).toEqual([]);
});

Expand All @@ -47,6 +53,20 @@ describe("MASA CLI", () => {
expect(result.error).toEqual([]);
});

it("applies the public-safety audit to publisher conformance", async () => {
const recordPath = join(
import.meta.dirname,
"../../examples/0.1.0/invalid/public-local-path.masa.json",
);
const result = capture();

await expect(
runCli(["conformance", "publisher", recordPath, "--json"], result.io),
).resolves.toBe(1);
expect(result.out.join("\n")).toContain("MASA_PUBLIC_PATH");
expect(result.error).toEqual([]);
});

it("emits bundle diagnostics and exit code 1 when verify fails", async () => {
const root = await temporaryRoot();
const bundle = join(root, "broken.masa");
Expand Down
22 changes: 13 additions & 9 deletions cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { dirname, extname, join, resolve } from "node:path";
import { pathToFileURL } from "node:url";
import {
createPublicProjection,
MASA_PROTOCOL_VERSION,
MASA_REFERENCE_IMPLEMENTATION_VERSION,
parseJsonStrict,
referenceCapabilitySet,
stableStringify,
Expand Down Expand Up @@ -136,8 +138,8 @@ function processingTemplate(operation: string): Record<string, unknown> {
}
return {
requestType: "masa-processing-request",
requestVersion: "0.1.0",
masaVersion: "0.1.0",
requestVersion: MASA_PROTOCOL_VERSION,
masaVersion: MASA_PROTOCOL_VERSION,
id: PLACEHOLDER_ID,
createdAt: "2026-01-01T00:00:00Z",
operationType: `matter.${operation}`,
Expand Down Expand Up @@ -173,7 +175,7 @@ async function writeNewJson(path: string, value: unknown): Promise<void> {

function usage(): string {
return [
"MASA 0.1.0 local CLI",
`MASA local CLI ${MASA_REFERENCE_IMPLEMENTATION_VERSION} (protocol ${MASA_PROTOCOL_VERSION})`,
"",
"masa validate <record-or-bundle> [--json]",
"masa inspect <record-or-bundle> [--json]",
Expand All @@ -187,7 +189,7 @@ function usage(): string {
"masa lineage <record> <entity-id> [--direction ancestors|descendants|both] [--max-depth 1..64] [--json]",
"masa conformance <reader|writer|transformer|agent-host|publisher> <record> [--json]",
"masa schema list [--json]",
"masa schema show <name> [--version 0.1.0] [--json]",
`masa schema show <name> [--version ${MASA_PROTOCOL_VERSION}] [--json]`,
"masa capabilities [--json]"
].join("\n");
}
Expand All @@ -205,7 +207,6 @@ async function validateCommand(path: string): Promise<{ output: unknown; code: n

async function conformanceCommand(className: string, path: string): Promise<{ output: unknown; code: number }> {
const record = await loadRecord(resolve(path));
const validation = validateMatterRecord(record);
const requiredProfile: Record<string, string> = {
reader: "core",
writer: "core",
Expand All @@ -215,14 +216,17 @@ async function conformanceCommand(className: string, path: string): Promise<{ ou
};
const profile = requiredProfile[className];
if (!profile) throw new UsageError(`Unknown conformance class ${className}.`);
const validation = className === "publisher"
? auditPublicRecord(record)
: validateMatterRecord(record);
const profilePresent =
Array.isArray(record.profiles) &&
(record.profiles as readonly unknown[]).includes(profile);
const valid = validation.valid && profilePresent;
return {
output: {
suite: "masa-artifact-check",
suiteVersion: "0.1.0",
suiteVersion: MASA_REFERENCE_IMPLEMENTATION_VERSION,
masaVersion: typeof record.masaVersion === "string" ? record.masaVersion : "undeclared",
class: className,
profile,
Expand Down Expand Up @@ -369,9 +373,9 @@ export async function runCli(argv: readonly string[], io: CliIo = defaultIo): Pr
return 0;
}
if (subcommand === "show" && schemaName) {
const version = option(args, "version") ?? "0.1.0";
if (version !== "0.1.0" || !/^[a-z][a-z0-9/-]*(?:\.schema\.json)?$/u.test(schemaName) || schemaName.includes("..")) {
throw new UsageError("Only a named MASA 0.1.0 schema may be shown.");
const version = option(args, "version") ?? MASA_PROTOCOL_VERSION;
if (version !== MASA_PROTOCOL_VERSION || !/^[a-z][a-z0-9/-]*(?:\.schema\.json)?$/u.test(schemaName) || schemaName.includes("..")) {
throw new UsageError(`Only a named MASA ${MASA_PROTOCOL_VERSION} schema may be shown.`);
}
const schema = getEmbeddedSchema(schemaName);
if (schema === undefined) throw new UsageError(`Unknown MASA schema ${schemaName}.`);
Expand Down
12 changes: 6 additions & 6 deletions conformance/0.1.0/evidence/agent-host.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"extensions": {},
"fixtureManifestDigest": {
"algorithm": "sha-256",
"byteLength": 298233,
"digest": "0240f5403d9d626c3eef75a55eb640cea84cf5b6d17d2824fe4874561c27be95",
"byteLength": 352859,
"digest": "7f57b4870c2414936114ce906258e1d4816be340d1c3c591cb95eec80bc9cdea",
"status": "verified",
"verifiedAt": "2026-08-07T16:28:56.467Z"
"verifiedAt": "2026-08-09T19:23:54.499Z"
},
"id": "urn:uuid:10000000-0000-4000-8000-000000000004",
"implementation": {
"name": "MASA local TypeScript reference",
"version": "0.1.0"
"version": "0.1.1"
},
"masaVersion": "0.1.0",
"migrationStatus": "not_applicable",
Expand All @@ -22,12 +22,12 @@
"runtime": "node v22.22.3"
},
"profile": "agent",
"runAt": "2026-08-07T16:28:56.467Z",
"runAt": "2026-08-09T19:23:54.499Z",
"status": "conformant",
"subject": "@sonicfield/masa workspace",
"suite": {
"name": "masa-typescript-reference-conformance",
"version": "0.1.0"
"version": "0.1.1"
},
"tests": [
{
Expand Down
12 changes: 6 additions & 6 deletions conformance/0.1.0/evidence/publisher.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"extensions": {},
"fixtureManifestDigest": {
"algorithm": "sha-256",
"byteLength": 298233,
"digest": "0240f5403d9d626c3eef75a55eb640cea84cf5b6d17d2824fe4874561c27be95",
"byteLength": 352859,
"digest": "7f57b4870c2414936114ce906258e1d4816be340d1c3c591cb95eec80bc9cdea",
"status": "verified",
"verifiedAt": "2026-08-07T16:28:56.467Z"
"verifiedAt": "2026-08-09T19:23:54.499Z"
},
"id": "urn:uuid:10000000-0000-4000-8000-000000000005",
"implementation": {
"name": "MASA local TypeScript reference",
"version": "0.1.0"
"version": "0.1.1"
},
"masaVersion": "0.1.0",
"migrationStatus": "not_applicable",
Expand All @@ -22,12 +22,12 @@
"runtime": "node v22.22.3"
},
"profile": "publication",
"runAt": "2026-08-07T16:28:56.467Z",
"runAt": "2026-08-09T19:23:54.499Z",
"status": "conformant",
"subject": "@sonicfield/masa workspace",
"suite": {
"name": "masa-typescript-reference-conformance",
"version": "0.1.0"
"version": "0.1.1"
},
"tests": [
{
Expand Down
12 changes: 6 additions & 6 deletions conformance/0.1.0/evidence/reader.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"extensions": {},
"fixtureManifestDigest": {
"algorithm": "sha-256",
"byteLength": 298233,
"digest": "0240f5403d9d626c3eef75a55eb640cea84cf5b6d17d2824fe4874561c27be95",
"byteLength": 352859,
"digest": "7f57b4870c2414936114ce906258e1d4816be340d1c3c591cb95eec80bc9cdea",
"status": "verified",
"verifiedAt": "2026-08-07T16:28:56.467Z"
"verifiedAt": "2026-08-09T19:23:54.499Z"
},
"id": "urn:uuid:10000000-0000-4000-8000-000000000001",
"implementation": {
"name": "MASA local TypeScript reference",
"version": "0.1.0"
"version": "0.1.1"
},
"masaVersion": "0.1.0",
"migrationStatus": "not_applicable",
Expand All @@ -22,12 +22,12 @@
"runtime": "node v22.22.3"
},
"profile": "core",
"runAt": "2026-08-07T16:28:56.467Z",
"runAt": "2026-08-09T19:23:54.499Z",
"status": "conformant",
"subject": "@sonicfield/masa workspace",
"suite": {
"name": "masa-typescript-reference-conformance",
"version": "0.1.0"
"version": "0.1.1"
},
"tests": [
{
Expand Down
12 changes: 6 additions & 6 deletions conformance/0.1.0/evidence/transformer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
"extensions": {},
"fixtureManifestDigest": {
"algorithm": "sha-256",
"byteLength": 298233,
"digest": "0240f5403d9d626c3eef75a55eb640cea84cf5b6d17d2824fe4874561c27be95",
"byteLength": 352859,
"digest": "7f57b4870c2414936114ce906258e1d4816be340d1c3c591cb95eec80bc9cdea",
"status": "verified",
"verifiedAt": "2026-08-07T16:28:56.467Z"
"verifiedAt": "2026-08-09T19:23:54.499Z"
},
"id": "urn:uuid:10000000-0000-4000-8000-000000000003",
"implementation": {
"name": "MASA local TypeScript reference",
"version": "0.1.0"
"version": "0.1.1"
},
"masaVersion": "0.1.0",
"migrationStatus": "not_applicable",
Expand All @@ -22,12 +22,12 @@
"runtime": "node v22.22.3"
},
"profile": "transformation",
"runAt": "2026-08-07T16:28:56.467Z",
"runAt": "2026-08-09T19:23:54.499Z",
"status": "conformant",
"subject": "@sonicfield/masa workspace",
"suite": {
"name": "masa-typescript-reference-conformance",
"version": "0.1.0"
"version": "0.1.1"
},
"tests": [
{
Expand Down
Loading