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 .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This repository is the canonical source of the workspace.json specification, JSO
- Define contracts and deterministic reference behavior here.
- Producer and generation orchestration belong in `workspacejson/cli`.
- MCP, Codex, editor, and other host integrations belong in `workspacejson/integrations`.
- Site rendering and assembled documentation belong in `workspacejson/site`.
- Site rendering and assembled documentation belong in `workspacejson/workspacejson.dev`.
- Never import `@marcelle-labs/*`, private Vreko source, or depend on `workspace.vreko.json`.
- The standard is descriptive, never prescriptive.
- The committed `.agents/workspace.json` must remain useful without a daemon.
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This repository owns contracts, not implementations. Before adding anything, che

- **No producer code.** Generation lives in `workspacejson/cli`.
- **No host integrations.** MCP, Codex and VS Code live in `workspacejson/integrations`.
- **No site rendering.** Documentation assembly lives in `workspacejson/site`.
- **No site rendering.** Documentation assembly lives in `workspacejson/workspacejson.dev`.
- **No proprietary references.** `@marcelle-labs/*`, private Vreko source and
`workspace.vreko.json` are prohibited.
- **Descriptive, never prescriptive.** No enforcement, approval-gate or
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ and its deterministic reference behavior. It publishes `@workspacejson/spec` and

- Read [`OWNERSHIP.md`](./OWNERSHIP.md) — it states what belongs here and what
belongs in `workspacejson/cli`, `workspacejson/integrations` or
`workspacejson/site`.
`workspacejson/workspacejson.dev`.
- Read [`GOVERNANCE.md`](./GOVERNANCE.md) — changes to the normative surface need
an architecture decision record **merged before** implementation. Finding that
out after writing the code is the expensive way.
Expand Down
2 changes: 1 addition & 1 deletion GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This repository decides:

It does not decide how artifacts are produced, how hosts integrate, or how the
website presents any of it. Those live in `workspacejson/cli`,
`workspacejson/integrations` and `workspacejson/site` respectively.
`workspacejson/integrations` and `workspacejson/workspacejson.dev` respectively.
[`OWNERSHIP.md`](./OWNERSHIP.md) states the full boundary; it is enforced by
`scripts/check-architecture.mjs` in CI rather than by convention.

Expand Down
6 changes: 3 additions & 3 deletions OWNERSHIP.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ what a coordinated authority transfer must do.
## Consumes

- no implementation-repository internals
- no `workspacejson/cli`, `workspacejson/integrations` or `workspacejson/site` code
- no `workspacejson/cli`, `workspacejson/integrations` or `workspacejson/workspacejson.dev` code
- no `@marcelle-labs/*` package, no private Vreko source, no `workspace.vreko.json`

`@workspacejson/rules` depends on `@workspacejson/spec` through the shared pnpm
Expand All @@ -40,7 +40,7 @@ rewrites it to an exact version before publication.

- producer or generation orchestration — that is `workspacejson/cli`
- host integrations (MCP, Codex, VS Code) — that is `workspacejson/integrations`
- site rendering or documentation assembly — that is `workspacejson/site`
- site rendering or documentation assembly — that is `workspacejson/workspacejson.dev`
- private Vreko behavior or any proprietary sidecar
- **prescriptive policy** — enforcement rules, approval gates, merge blocking.
The standard describes what a repository is; it does not dictate what a team
Expand All @@ -55,7 +55,7 @@ workspacejson/standard <- depends on NONE of the others
workspacejson/cli workspacejson/integrations
\ /
workspacejson/site
workspacejson/workspacejson.dev
```

Proprietary repositories may consume released Apache-2.0 `@workspacejson/*`
Expand Down
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ This is one of four, with one-way ownership:
| **`workspacejson/standard`** *(this repo)* | specification, JSON Schema, standard types, validation semantics, deterministic rules, compatibility profiles, conformance fixtures, ADRs and governance |
| `workspacejson/cli` | production and generation — the producer, repository scanning, deterministic reconciliation, CLI distribution |
| `workspacejson/integrations` | host adapters — MCP, Codex, VS Code, skills and plugins |
| `workspacejson/site` | assembled, published documentation at `workspacejson.dev` |
| `workspacejson/workspacejson.dev` | assembled, published documentation at `workspacejson.dev` |

Dependency direction is one-way:

Expand All @@ -45,7 +45,7 @@ workspacejson/standard
workspacejson/cli workspacejson/integrations
\ /
workspacejson/site
workspacejson/workspacejson.dev
```

**This repository depends on none of the other three.** That is enforced
Expand Down Expand Up @@ -231,17 +231,27 @@ Stated here rather than discovered later:
- **This repository cannot publish.** Both packages are released from the
historical repository, which holds the only credential. That is deliberate and
enforced in CI.
- **The schema `$id` host disagrees with the canonical domain.** The schema
declares the `www.` host while the package manifests use the bare domain. Both
serve the schema, so nothing is broken, but the strings differ. Reconciling
them changes schema bytes and is tracked as a normative change.
- **The schema `$id` is reconciled on `main` but not in the released bytes.**
`main` declares the bare domain, matching the package manifests. The published
`@workspacejson/spec@0.4.4` still serves the `www.` host, because the fix
changes schema bytes and has not been released. Both hosts serve the schema,
so nothing is broken — but do not read `main` as released truth here.
- **`v1.json` is a legacy filename**, not a claim that the format is at 1.0.
- **Four ambient interop shims are retained** in `types/ambient.d.ts` for
`simple-git`, `remark` and `ajv`. They are real CJS/ESM mismatches in
third-party packages, tracked as their own work rather than papered over.
- **The repository is private and on a plan without branch protection.** Both
constraints and the gate they create before any publication authority are
recorded in [`docs/repository-settings.md`](./docs/repository-settings.md).
- **`main` has no enforceable independent-review path.** Branch protection is
enabled — required checks on Node 20/22 plus four-path producer conformance,
dismissed stale approvals, code-owner review, conversation resolution, and no
force-push or deletion. But the general `required_approving_review_count` is
`0`; code-owner review is enabled and does block affected pull requests, yet
every path in [`.github/CODEOWNERS`](./.github/CODEOWNERS) is owned solely by
`@qmarcelle`, who authors the changes — and an author cannot approve their own
pull request. Administrator enforcement is also off, so the administrator can
bypass the protection entirely. The controls exist; no combination of them
currently produces review by a second person. Recorded, with the remediation
it actually requires, in
[`docs/repository-settings.md`](./docs/repository-settings.md).

## License

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ This repository owns the specification, schema, types, validation semantics and
deterministic rules. Issues in repository generation belong to
`workspacejson/cli`; issues in host adapters belong to
`workspacejson/integrations`; issues in the published website belong to
`workspacejson/site`.
`workspacejson/workspacejson.dev`.

## Publication note

Expand Down
2 changes: 1 addition & 1 deletion SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ costs you a round trip:
| `.agents/workspace.json` is not generated, or generated wrongly | `workspacejson/cli` |
| A repository scan produced bad or missing data | `workspacejson/cli` |
| MCP, Codex or VS Code integration misbehaves | `workspacejson/integrations` |
| Documentation on `workspacejson.dev` is wrong or stale | `workspacejson/site` |
| Documentation on `workspacejson.dev` is wrong or stale | `workspacejson/workspacejson.dev` |

If a validation error is *reported by* a producer but the schema itself is wrong,
it belongs here. When in doubt, file here and it will be redirected.
Expand Down
50 changes: 43 additions & 7 deletions docs/conformance.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,19 +201,55 @@ contract.

Stated plainly, because a conformance document that hides them is misleading:

- **There is no external conformance suite.** An independent implementation
cannot currently run a standard battery to claim conformance. What exists is
this repository's own examples and its reference validator.
- **There is no self-service conformance battery for an unaided implementer.**
A producer suite exists and is described below, but running it requires a
candidate path supplied by the caller. An independent implementation cannot
yet point at a single published battery and claim conformance without that
step. What ships otherwise is this repository's own examples and its
reference validator.
- **`validateLegacy()` has no shipped example.** All four examples are v0.3 or
v0.4, so the legacy path is covered by unit tests but not by an executable
fixture a third party can point at.
- **There are no negative examples.** The examples prove that valid documents
validate. They do not prove that invalid documents are rejected — that is
covered only by unit tests inside the package.
- **Producer conformance is not mechanically checked here.** The obligations
listed at the top of this document — `manual` preservation, material-change
write semantics — are stated in the contract and tested by producers, not
verified by a fixture in this repository.

### Producer conformance IS mechanically checked here

This bullet previously said the opposite. That was true when written and became
false when the executable contract landed; it is corrected rather than quietly
dropped.

`scripts/check-producer-conformance.mjs` is the standard's assertion about what
any conforming producer must do. It measures an external candidate — the
producer does not grade itself:

```bash
WORKSPACEJSON_CLI_CANDIDATE=/path/to/cli/packages/cli \
pnpm run check:conformance

pnpm run check:conformance:test # the mutation red tests
```

It asserts five groups: `generated.fileIndex` populated from repository
evidence, `generated.frameworkManifest` populated from repository evidence,
`manual.*` preserved verbatim and never fabricated, invalid artifacts failing
safely without destroying human evidence, and producer identity plus
determinism plus direct/mediated parity. It imports this repository's own
validator rather than re-implementing it, so there is no second source of truth
to drift.

The mutation tests assert that each mutation actually changed bytes and that
the suite goes red *on the expected check* rather than on any failure, with a
baseline case asserting the unmutated candidate is accepted — so the suite
cannot pass by rejecting everything.

**What it deliberately does not assert.** Nothing about per-file values inside
`generated.fileIndex`. `FileIndexEntry` declares every value field optional, so
`{}` is conformant. Those values are behavioral and git-derived, and whether
they may enter the stable contract is an open determination this repository
does not own — recorded as ADR-003 amendment A-004. Requiring them here would
pre-empt that ruling and fail a producer that is behaving correctly.

Closing these gaps is real work with real design questions, and none of it is
claimed as done.
76 changes: 64 additions & 12 deletions docs/repository-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ now enabled:

| Control | Status | Notes |
| -- | -- | -- |
| Branch protection | **enabled** | PR + 1 approving review + CI on Node 20/22 + conversation resolution + codeowner review + block force-push/deletion. See below. |
| Branch protection | **enabled; no independent-review path** | PR + CI on Node 20/22 + conversation resolution + codeowner review + block force-push/deletion. **General approving-review count is `0`, the sole code owner authors the changes, and admin enforcement is off.** See below. |
| Secret scanning | **enabled** | Free for public repositories. |
| Secret scanning push protection | **enabled** | Blocks commits containing detected secrets. |
| Private vulnerability reporting | **enabled** | The advisory form at [`SECURITY.md`](../SECURITY.md) now resolves. |
Expand All @@ -68,22 +68,74 @@ now enabled:

## Branch protection

Branch protection is **enabled** on `main` as of 2026-07-28. The protection
requires:
Branch protection is **enabled** on `main` as of 2026-07-28. Measured against the
GitHub API on 2026-08-04, it requires:

- a pull request with at least one approving review;
- required status checks: `test (20)`, `test (22)`, and `Four-path producer
conformance`;
- a pull request;
- required status checks, strict: `test (20)`, `test (22)`, and `Four-path
producer conformance`;
- dismiss stale approvals on new commits;
- require conversation resolution;
- block force pushes and branch deletion;
- require review from code owners, so changes to the schema, the guards and the
release documents reach a maintainer — see [`.github/CODEOWNERS`](../.github/CODEOWNERS).
- enforce on admins.
- require review from code owners — see [`.github/CODEOWNERS`](../.github/CODEOWNERS).

This was a hard gate before publication authority. The protection is now in
place, so the authority transfer in `.github/RELEASE-AUTHORITY.md` can proceed
without creating a supply-chain window.
Two controls this document previously claimed are **not** in place:

| Claimed | Measured |
| -- | -- |
| a pull request with at least one approving review | `required_approving_review_count: 0` |
| enforce on admins | `enforce_admins: false` |

No ruleset supplies these separately; `GET /repos/workspacejson/standard/rulesets`
returns `[]`.

### The actual defect: no enforceable independent-review path

These are four separate facts, and the defect is what they produce together —
not any one of them alone.

1. **The general approving-review count is `0`.** No count-based approval is
required, so paths a code-owner rule does not reach are unprotected by review.
2. **Code-owner review is enabled and does bind.** `require_code_owner_reviews`
is an independent control: it blocks an affected pull request until a code
owner approves it, regardless of the general count. Nothing here should be
read as saying that control is inert — it is not.
3. **Every path has exactly one code owner, and that owner authors the changes.**
[`.github/CODEOWNERS`](../.github/CODEOWNERS) assigns `*` and every specific
path to `@qmarcelle`. GitHub does not permit a pull-request author to approve
their own pull request, so a self-authored change cannot satisfy the
code-owner requirement from within.
4. **Administrator enforcement is off.** `enforce_admins: false` means the
administrator — the same account — can bypass the protection entirely.

The controls are configured. What is missing is a *second person*: no combination
of the above currently results in a change being reviewed by someone other than
its author.

**This is not currently a credentialed package-publication risk**, because this
repository holds no npm credential and ships no release workflow. It is not
harmless in general — `main` here is the public canonical source of the standard,
and unreviewed changes to the schema, the guards, or the governance documents
land the same way.

### Remediation

Raising the approval count alone does not fix this. All four are required:

1. **At least one independent maintainer or code owner** able to review
`@qmarcelle`-authored changes. Without this, nobody can satisfy point 3 above.
2. **At least one required approval** (`required_approving_review_count >= 1`),
so review is required on paths no code-owner rule reaches.
3. **Administrator enforcement**, or a no-bypass ruleset carrying a deliberately
bounded and documented release exception — bypass should be an explicit,
narrow act rather than the default posture.
4. **Continued protection of `.github/CODEOWNERS` itself**, so the ownership map
cannot be edited to route around the requirement. This is already in place at
`.github/CODEOWNERS:29` and must survive any change made for points 1–3.

`.github/RELEASE-AUTHORITY.md` and the migration plan both treat protected,
reviewed release paths as a precondition for holding a credential. This must be
closed *before* publication authority transfers, not after.

## Repository metadata

Expand Down