Skip to content
Closed
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/OPERABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Release publication occurs only from an exact integrated protected head. The rel
Before publication:

1. fetch the current protected `main` ref and require the release tag event commit SHA to equal that exact integration tip, not merely be an ancestor of it;
2. build exactly three regular top-level release files: exactly one npm tarball, exactly one Inkspan Office wheel, and `SHA256SUMS`;
2. build exactly four regular top-level release files: exactly one npm tarball, exactly one Inkspan Office wheel, `inkspan.spdx.json`, and `SHA256SUMS`;
3. reject missing, duplicate, non-regular, stale, or unexpected local entries and verify the local digests;
4. after upload, query the authenticated paginated GitHub Releases API and require the resumed remote draft asset-name set to equal the local release directory exactly;
5. require every remote asset state to be uploaded and every GitHub-reported `sha256:` digest to equal the exact transferred local file digest;
Expand Down
4 changes: 2 additions & 2 deletions docs/TEST_STRATEGY.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ At minimum, maintain regressions for:
- autosave stale validators, conflict/failure recovery, ambiguous transport outcomes, duplicate/no-op lifecycle transitions, callback exceptions, queue bounds, flush/close behavior, and durable-validator coherence;
- selection/revision races and document movement during asynchronous hashing;
- Office formula prefixes, invalid XML characters, malicious strings, path/publication races, invalid worksheet names, invalid freeze panes, cyclic input, pathological nesting, excessive container size, and partial write failure;
- package/release stale draft assets, unexpected or non-regular local entries, exact three-file inventory violations, incomplete remote uploads, GitHub-vs-local digest mismatch, stale exact-head evidence, mutable provenance inputs, and isolated packed-consumer behavior.
- package/release stale draft assets, unexpected or non-regular local entries, exact four-file inventory violations, incomplete remote uploads, GitHub-vs-local digest mismatch, stale exact-head evidence, mutable provenance inputs, and isolated packed-consumer behavior.

## Concurrency and failure testing

Expand All @@ -68,7 +68,7 @@ Host persistence transactions, tenant isolation, distributed collaboration autho

A release candidate requires the exact integrated protected head to satisfy applicable CI, security, JavaScript/TypeScript 100% statement/branch/function/line coverage, Office coverage.py 100% report plus public-docstring completeness, package-consumer, accessibility, browser differential, Office artifact, SBOM/provenance, reproducibility, unresolved-thread, actually required independent-review, and release-workflow gates. Queued, skipped-required, cancelled, absent, stale-head, predecessor-head, status-only, or synthetic-merge evidence is not accepted as success.

The release workflow must also satisfy the normative `docs/CONTRACTS.md` draft inventory contract: exactly one npm tarball, exactly one Office wheel, and `SHA256SUMS`; no other top-level entry; remote uploaded asset names exactly equal local names; and every GitHub-reported `sha256:` digest equals the exact transferred local file digest. Missing, stale, unexpected, non-regular, incomplete, or digest-mismatched assets are failures, not cleanup opportunities.
The release workflow must also satisfy the normative `docs/CONTRACTS.md` draft inventory contract: exactly one npm tarball, exactly one Office wheel, `inkspan.spdx.json`, and `SHA256SUMS`; no other top-level entry; remote uploaded asset names exactly equal local names; and every GitHub-reported `sha256:` digest equals the exact transferred local file digest. Missing, stale, unexpected, non-regular, incomplete, or digest-mismatched assets are failures, not cleanup opportunities.

The 0.6.0 rich-clipboard release line specifically requires the protected dependency-locked **Playwright 1.62.0** Chromium, Firefox, and WebKit differential gate on the exact integrated protected release candidate before publication. Deterministic jsdom coverage remains useful but is not a substitute for browser-engine acceptance. Tagged release evidence must be generated anew from the release candidate and must verify the exact packed npm artifact, not merely reuse a previously green feature-branch run.

Expand Down
40 changes: 40 additions & 0 deletions src/releaseCanonicalArtifactInventory.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';

import { describe, expect, it } from 'vitest';

const repositoryFile = (path: string): string =>
readFileSync(resolve(process.cwd(), path), 'utf8');

describe('canonical release artifact inventory', () => {
it('keeps protected release documents aligned with the four-file SBOM boundary', () => {
const contracts = repositoryFile('docs/CONTRACTS.md');
const operability = repositoryFile('docs/OPERABILITY.md');
const releaseSecurity = repositoryFile('docs/release-security.md');
const testStrategy = repositoryFile('docs/TEST_STRATEGY.md');

expect(releaseSecurity).toContain(
'Each successful GitHub release contains exactly four files',
);
expect(releaseSecurity).toContain('`inkspan.spdx.json`');

expect(contracts).toContain('exactly four regular top-level files');

Check failure on line 21 in src/releaseCanonicalArtifactInventory.test.ts

View workflow job for this annotation

GitHub Actions / build-and-test

src/releaseCanonicalArtifactInventory.test.ts > canonical release artifact inventory > keeps protected release documents aligned with the four-file SBOM boundary

AssertionError: expected '# Inkspan Interface and Integration C…' to contain 'exactly four regular top-level files' - Expected + Received - exactly four regular top-level files + # Inkspan Interface and Integration Contracts + + Status: Protected-main canonical baseline + + This document is the discoverable contract index for Inkspan's public product boundaries. Protected `main` remains the implementation authority. Open pull requests may describe Proposed behavior, but they are not shipped until protected integration and exact-head acceptance. + + ## Contract principles + + Inkspan owns deterministic editor state, versioned document-envelope semantics, local revision/evidence primitives, local autosave ordering, deterministic conversion, accessibility metadata, and provider-neutral adapter behavior. The embedding **host** owns transport, authentication, authorization, tenant isolation, durable persistence, credentials, migrations, retention, deployment, durable audit storage, collaboration-provider lifecycle, and model-use policy. + + Every contract is versioned or otherwise compatibility-bounded, deterministic where the domain permits it, fail closed on malformed or unsupported inputs, and explicit about degraded behavior. No contract silently promotes generated output, model output, a local digest, a browser field, a collaboration update, or a workflow status into authorization or durable-persistence authority. + + ## Public package and module contract + + The root package may expose React/TipTap integration plus framework-independent helpers. Framework-independent subpaths must remain consumable without React, React DOM, TipTap UI, ProseMirror view, Yjs, browser globals, network access, database clients, credentials, or model SDKs unless that subpath's versioned contract explicitly requires them. + + Package exports, declaration files, runtime support, and packed ESM/CommonJS/strict-TypeScript consumers are release evidence. A source file being present is not sufficient proof that a public contract is packaged correctly. + + Protected `main` includes the React-free `@contextualwisdomlab/cwl-editor/text-position-selector` subpath for deterministic W3C selector projection. The root editor surface remains the authority for capturing one immutable editor state and binding that projection to an exact document revision. + + ## Document envelope and revision contract + + The **document envelope** is a versioned boundary carrying schema identity and supported document content. Current-schema parsing validates strict JSON/UTF-8 and active schema requirements before canonicalization or hashing. Unknown schema migration remains host-owned. + + Envelope identity routing is implemented on protected `main` through `inspectDocumentEnvelopeIdentity()` and `inspectDocumentEnvelopeIdentityBytes()`, exported by the root package and the framework-independent `./envelope-identity` subpath. The inspectors validate a complete bounded envelope and return only frozen `{ schemaId, schemaVersion }` routing metadata. They do not return `documentJson`, accept unknown document semantics as current, execute a migration, authorize access, or claim durable persistence. + + Canonical revision evidence is content-equality metadata only. It is not an actor identity, tenant identity, authorization grant, signature, timestamp, durable write receipt, or bearer credential. Identity routing does not weaken the strict current-schema parser or transfer schema-registry, migration, persistence, rollback, or recovery authority from the host. + + Compatibility rule: a new schema or incompatible interpretation requires an explicit new versioned contract and migration story; existing persisted semantics are not silently redefined. + + ## Editor authoring contract + + Markdown/HTML authoring uses the supported TipTap/ProseMirror editor surface as the deterministic editing authority. Import/export adapters must state which constructs are supported, lossy, or rejected. Rendered or exported representations do not silently become the canonical source document. + + T
expect(contracts).toContain('`inkspan.spdx.json`');
expect(contracts).toMatch(/release evidence \| exact four-file draft inventory/u);

expect(testStrategy).toContain('exact four-file inventory violations');
expect(testStrategy).toContain(
'exactly one npm tarball, exactly one Office wheel, `inkspan.spdx.json`, and `SHA256SUMS`',
);

expect(operability).toContain('build exactly four regular top-level release files');
expect(operability).toContain(
'exactly one npm tarball, exactly one Inkspan Office wheel, `inkspan.spdx.json`, and `SHA256SUMS`',
);

for (const document of [contracts, testStrategy, operability]) {
expect(document).not.toContain('exactly three regular top-level files');
expect(document).not.toContain('exact three-file draft inventory');
}
});
});
Loading