diff --git a/docs/adr/0001-sourceos-shell-boundary.md b/docs/adr/0001-sourceos-shell-boundary.md new file mode 100644 index 0000000..f3dc866 --- /dev/null +++ b/docs/adr/0001-sourceos-shell-boundary.md @@ -0,0 +1,35 @@ +# ADR 0001 — sourceos-shell contract boundary + +## Status +Accepted + +## Context + +The SourceOS shell work introduces a product/runtime surface for: + +- Markdown-first authoring +- PDF derivation, signing, and validation +- search routing decisions +- comment/review signal surfaces +- annotation export +- run reports and Noether diagnostics +- publish and mirror receipts + +These objects are exchanged across product code, Linux realization, and publishing/provenance systems. They should not be defined ad hoc inside runtime repositories. + +## Decision + +The repository split is: + +- `SourceOS-Linux/sourceos-shell` — product/runtime code +- `SourceOS-Linux/sourceos-spec` — shared machine-readable contracts +- `SociOS-Linux/source-os` — Linux realization surfaces +- `SociOS-Linux/albert` — temporary launcher bridge only + +The canonical object shapes for shell/document/provenance/search/report flows are defined here in `sourceos-spec`. + +## Consequences + +- shell/runtime code consumes generated types from this repository +- Linux realization refers back to these contracts instead of redefining them +- publish, mirror, validation, and routing receipts become interoperable across implementations diff --git a/examples/artifact-manifest.json b/examples/artifact-manifest.json new file mode 100644 index 0000000..1e25afd --- /dev/null +++ b/examples/artifact-manifest.json @@ -0,0 +1,17 @@ +{ + "artifactId": "demo-report", + "source": { + "path": "content/draft/demo-report.md", + "commit": "deadbeef" + }, + "unsignedPdf": "content/derived/pdf/demo-report.pdf", + "signedPdf": "content/derived/pdf_signed/demo-report.signed.pdf", + "sha256": "0123cafe0123cafe0123cafe0123cafe", + "signed": true, + "pdfa": true, + "signer": "CN=Docs PSigner", + "signature": { + "type": "PKCS#7", + "issuer": "CN=Docs PSigner" + } +} diff --git a/examples/comment-signal.json b/examples/comment-signal.json new file mode 100644 index 0000000..e2b1165 --- /dev/null +++ b/examples/comment-signal.json @@ -0,0 +1,7 @@ +{ + "commentId": "comment-123", + "genuineProb": 0.83, + "sarcasmProb": 0.12, + "experience": "experienced", + "verified": true +} diff --git a/examples/pdf-validation-report.json b/examples/pdf-validation-report.json new file mode 100644 index 0000000..c9bfa33 --- /dev/null +++ b/examples/pdf-validation-report.json @@ -0,0 +1,12 @@ +{ + "artifactId": "demo-report", + "validatedAt": "2026-04-16T22:05:00Z", + "pdfcpu": { + "ok": true, + "checks": ["xref", "metadata", "page-tree"] + }, + "verapdf": { + "ok": true, + "flavour": "PDF/A-2b" + } +} diff --git a/examples/search-route-decision.json b/examples/search-route-decision.json new file mode 100644 index 0000000..f293294 --- /dev/null +++ b/examples/search-route-decision.json @@ -0,0 +1,7 @@ +{ + "scope": "files", + "provider": "linux_files", + "query": "report.pdf", + "routedAt": "2026-04-16T22:10:00Z", + "redundantSearchPrevented": true +} diff --git a/examples/signed-artifact.json b/examples/signed-artifact.json new file mode 100644 index 0000000..dcb61ce --- /dev/null +++ b/examples/signed-artifact.json @@ -0,0 +1,8 @@ +{ + "artifactId": "demo-report", + "signer": "CN=Docs PSigner", + "algorithm": "PKCS#7", + "timestamp": "2026-04-16T22:00:00Z", + "issuer": "CN=Docs PSigner", + "signatureRef": "content/derived/pdf_signed/demo-report.signed.pdf" +} diff --git a/schemas/ArtifactManifest.json b/schemas/ArtifactManifest.json new file mode 100644 index 0000000..f879f42 --- /dev/null +++ b/schemas/ArtifactManifest.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:srcos:schema:ArtifactManifest", + "title": "ArtifactManifest", + "type": "object", + "required": ["artifactId", "source", "unsignedPdf", "sha256", "signed", "pdfa"], + "properties": { + "artifactId": {"type": "string"}, + "source": { + "type": "object", + "required": ["path", "commit"], + "properties": { + "path": {"type": "string"}, + "commit": {"type": "string"} + }, + "additionalProperties": false + }, + "unsignedPdf": {"type": "string"}, + "signedPdf": {"type": ["string", "null"]}, + "sha256": {"type": "string"}, + "signed": {"type": "boolean"}, + "pdfa": {"type": "boolean"}, + "signer": {"type": ["string", "null"]}, + "signature": {"type": ["object", "null"]} + }, + "additionalProperties": false +} diff --git a/schemas/CommentSignal.json b/schemas/CommentSignal.json new file mode 100644 index 0000000..553edde --- /dev/null +++ b/schemas/CommentSignal.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:srcos:schema:CommentSignal", + "title": "CommentSignal", + "type": "object", + "required": ["commentId", "genuineProb", "sarcasmProb", "experience"], + "properties": { + "commentId": {"type": "string"}, + "genuineProb": {"type": "number", "minimum": 0, "maximum": 1}, + "sarcasmProb": {"type": "number", "minimum": 0, "maximum": 1}, + "experience": {"type": "string", "enum": ["new", "experienced"]}, + "verified": {"type": ["boolean", "null"]} + }, + "additionalProperties": false +} diff --git a/schemas/PdfValidationReport.json b/schemas/PdfValidationReport.json new file mode 100644 index 0000000..9f46068 --- /dev/null +++ b/schemas/PdfValidationReport.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:srcos:schema:PdfValidationReport", + "title": "PdfValidationReport", + "type": "object", + "required": ["artifactId", "validatedAt", "pdfcpu", "verapdf"], + "properties": { + "artifactId": {"type": "string"}, + "validatedAt": {"type": "string", "format": "date-time"}, + "pdfcpu": { + "type": "object", + "required": ["ok"], + "properties": { + "ok": {"type": "boolean"}, + "checks": {"type": "array", "items": {"type": "string"}} + }, + "additionalProperties": true + }, + "verapdf": { + "type": "object", + "required": ["ok"], + "properties": { + "ok": {"type": "boolean"}, + "flavour": {"type": ["string", "null"]} + }, + "additionalProperties": true + } + }, + "additionalProperties": false +} diff --git a/schemas/SearchRouteDecision.json b/schemas/SearchRouteDecision.json new file mode 100644 index 0000000..fee8312 --- /dev/null +++ b/schemas/SearchRouteDecision.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:srcos:schema:SearchRouteDecision", + "title": "SearchRouteDecision", + "type": "object", + "required": ["scope", "provider", "query"], + "properties": { + "scope": {"type": "string", "enum": ["apps", "files", "web"]}, + "provider": {"type": "string"}, + "query": {"type": "string"}, + "routedAt": {"type": ["string", "null"], "format": "date-time"}, + "redundantSearchPrevented": {"type": ["boolean", "null"]} + }, + "additionalProperties": false +} diff --git a/schemas/SignedArtifact.json b/schemas/SignedArtifact.json new file mode 100644 index 0000000..3fef384 --- /dev/null +++ b/schemas/SignedArtifact.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "urn:srcos:schema:SignedArtifact", + "title": "SignedArtifact", + "type": "object", + "required": ["artifactId", "signer", "algorithm", "timestamp"], + "properties": { + "artifactId": {"type": "string"}, + "signer": {"type": "string"}, + "algorithm": {"type": "string"}, + "timestamp": {"type": "string", "format": "date-time"}, + "issuer": {"type": ["string", "null"]}, + "signatureRef": {"type": ["string", "null"]} + }, + "additionalProperties": false +}