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
2 changes: 1 addition & 1 deletion docs/contract-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ The top-level **color** object is optional. When present it can include:

## Where contract semantics live in the repo

- **Schema file:** `packages/interfacectl-validator/src/schema/surfaces.web.contract.schema.json`. This is the authoritative JSON Schema. The CLI uses a bundled copy of this schema by default. You may override it with `--schema <path>` if needed.
- **Schema file:** `packages/interfacectl-validator/src/schema/web.surface.contract.schema.json`. This is the authoritative JSON Schema. The CLI uses a bundled copy of this schema by default. You may override it with `--schema <path>` if needed. Built-in contract schemas are named by surface runtime and contract type (e.g. `web.surface.contract.schema.json`), not by application.
- **Structure validation:** The function **validateContractStructure** in `packages/interfacectl-validator/src/index.ts` loads the schema and validates contract JSON (via AJV). It returns errors or the parsed contract.
- **Compliance evaluation:** The function **evaluateContractCompliance** in the same file takes a validated contract and a list of surface descriptors. It returns a validation summary with per-surface reports and violations. Compliance rules for fonts, colors, layout, motion, sections, and pageFrame are implemented in **evaluateSurfaceCompliance** in the same file.
- **CLI entry point:** The validate command is implemented in `packages/interfacectl-cli/src/commands/validate.ts`. It calls **collectSurfaceDescriptors** (in `packages/interfacectl-cli/src/descriptors/static-analysis.ts`) to gather descriptors from the codebase, then passes the contract and descriptors to **evaluateContractCompliance**. The CLI maps violation types to stable codes in this command implementation.
6 changes: 3 additions & 3 deletions docs/plans/contract-first-enforcement-alignment.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Interfacectl enforces this by:
## Contract Impact

### 1. Contract definition
The authoritative contract schema lives in `packages/interfacectl-validator/src/schema/surfaces.web.contract.schema.json`. Contracts are JSON files (default path `contracts/surfaces.web.contract.json` or `SURFACES_CONTRACT`). The schema already includes:
The authoritative contract schema lives in `packages/interfacectl-validator/src/schema/web.surface.contract.schema.json`. Contracts are JSON files (default path `contracts/surfaces.web.contract.json` or `SURFACES_CONTRACT`). The schema already includes:
- **Version and scope:** `contractId`, `version` (semver pattern).
- **Surfaces:** per-surface `requiredSections`, `allowedFonts`, `layout` (maxContentWidth, requiredContainers, optional pageFrame), deprecated `allowedColors`.
- **Sections:** `id`, `intent`, `description` (intent is present but not yet a first-class enforcement hook).
Expand Down Expand Up @@ -122,7 +122,7 @@ Migration: `allowedColors` is deprecated in favor of `color.sourceOfTruth` and `
## Implementation Outline

### Phase 0. Contract baseline (mostly done; align and document)
- **Reuse:** Contract schema is in `packages/interfacectl-validator/src/schema/surfaces.web.contract.schema.json`. Validation is `validateContractStructure` in `packages/interfacectl-validator/src/index.ts` (AJV). Error taxonomy is `DriftViolationType` and the code map in `packages/interfacectl-cli/src/commands/validate.ts` (e.g. `font.disallowed`).
- **Reuse:** Contract schema is in `packages/interfacectl-validator/src/schema/web.surface.contract.schema.json`. Validation is `validateContractStructure` in `packages/interfacectl-validator/src/index.ts` (AJV). Error taxonomy is `DriftViolationType` and the code map in `packages/interfacectl-cli/src/commands/validate.ts` (e.g. `font.disallowed`).
- **New/minimal:** Document the minimal authoritative contract (required fields, optional color policy, deprecated allowedColors). Optionally add a short "contract concepts" section to API.md or docs. No schema change required unless adding breaking/non-breaking metadata later.

### Phase 1. Generation-time gating (map to existing commands; optional alias)
Expand Down Expand Up @@ -167,7 +167,7 @@ Work in this phase is contingent on observing Phase 4 consumption patterns.
## Builder Checklist

Before implementation begins:
- **Contract location:** Canonical schema is `packages/interfacectl-validator/src/schema/surfaces.web.contract.schema.json`. Contract files are project-specific (default `contracts/surfaces.web.contract.json` or `SURFACES_CONTRACT`). Ownership is repo; surfaces.systems is the intended source of canonical definitions per strategy.
- **Contract location:** Canonical schema is `packages/interfacectl-validator/src/schema/web.surface.contract.schema.json`. Contract files are project-specific (default `contracts/surfaces.web.contract.json` or `SURFACES_CONTRACT`). Ownership is repo; surfaces.systems is the intended source of canonical definitions per strategy.
- **Generation-time gating:** Current CI (`.github/workflows/ci.yml`) runs verify, build, test only. Gating fits as an optional job (e.g. `interfacectl validate` or `enforce --mode fail` against a repo contract). Confirm with maintainers where to add it (e.g. on PR, on main, or as an optional job).
- **Runtime consumers:** No runtime consumers for compiled bundles exist yet. Before implementing `compile`, confirm at least one consumer or a concrete bundle format requirement; otherwise defer or define a minimal format and document it for future consumers.

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion packages/interfacectl-cli/dist/commands/generate-contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ export async function runGenerateContractCommand(options) {
await mkdir(path.dirname(contractPath), { recursive: true });
await mkdir(path.dirname(reportPath), { recursive: true });
const contractJson = stableStringify(contract);
const reportJson = stableStringify(report);
const reportForOutput = {
...report,
appRoot: path.relative(cwd, report.appRoot),
};
const reportJson = stableStringify(reportForOutput);
await writeFile(contractPath, `${contractJson}\n`, "utf-8");
await writeFile(reportPath, `${reportJson}\n`, "utf-8");
console.log(`Wrote contract: ${contractPath}`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://contracts.surfaces.local/surfaces.web.contract.schema.json",
"$schema": "https://contracts.surfaces.local/web.surface.contract.schema.json",
"contractId": "portable.fixture",
"version": "0.0.1",
"surfaces": [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://contracts.surfaces.local/surfaces.web.contract.schema.json",
"$schema": "https://contracts.surfaces.local/web.surface.contract.schema.json",
"contractId": "traceability.fixture",
"version": "0.0.1",
"surfaces": [
Expand Down
2 changes: 1 addition & 1 deletion packages/interfacectl-extractor/dist/extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function buildContract(surfaceId, extracted) {
? "Surfaces Web"
: surfaceId.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
return {
$schema: "https://contracts.surfaces.local/surfaces.web.contract.schema.json",
$schema: "https://contracts.surfaces.local/web.surface.contract.schema.json",
contractId: `${surfaceId}.generated`,
version: "0.1.0",
description: "Extracted from Next.js app (Phase 0).",
Expand Down
2 changes: 1 addition & 1 deletion packages/interfacectl-extractor/src/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function buildContract(

return {
$schema:
"https://contracts.surfaces.local/surfaces.web.contract.schema.json",
"https://contracts.surfaces.local/web.surface.contract.schema.json",
contractId: `${surfaceId}.generated`,
version: "0.1.0",
description: "Extracted from Next.js app (Phase 0).",
Expand Down
2 changes: 1 addition & 1 deletion packages/interfacectl-validator/dist/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import AjvModule from "ajv/dist/2020.js";
import addFormats from "ajv-formats";
import bundledSchema from "./schema/surfaces.web.contract.schema.json" with {
import bundledSchema from "./schema/web.surface.contract.schema.json" with {
type: "json"
};
const frozenBundledSchema = Object.freeze(bundledSchema);
Expand Down
Loading