diff --git a/Makefile b/Makefile index f5570ba..77abd02 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,12 @@ -.PHONY: validate validate-control-plane-examples validate-nlboot-examples validate-lattice-data-governai-examples validate-ops-history-examples validate-runtime-observability-examples validate-interpretability-examples validate-lifecycle-boundary-examples validate-svf-contracts validate-sync-cycle-receipts validate-onboarding-examples validate-runtime-causality-examples +.PHONY: validate validate-control-plane-examples validate-nlboot-examples validate-lattice-data-governai-examples validate-ops-history-examples validate-runtime-observability-examples validate-interpretability-examples validate-lifecycle-boundary-examples validate-svf-contracts validate-sync-cycle-receipts validate-onboarding-examples validate-runtime-causality-examples validate-labor-market-examples -validate: validate-control-plane-examples validate-nlboot-examples validate-lattice-data-governai-examples validate-ops-history-examples validate-runtime-observability-examples validate-interpretability-examples validate-lifecycle-boundary-examples validate-svf-contracts validate-sync-cycle-receipts validate-onboarding-examples validate-runtime-causality-examples +validate: validate-control-plane-examples validate-nlboot-examples validate-lattice-data-governai-examples validate-ops-history-examples validate-runtime-observability-examples validate-interpretability-examples validate-lifecycle-boundary-examples validate-svf-contracts validate-sync-cycle-receipts validate-onboarding-examples validate-runtime-causality-examples validate-labor-market-examples @echo "OK: validate" +validate-labor-market-examples: + python3 -m pip install --user jsonschema >/dev/null + python3 tools/validate_labor_market_examples.py + validate-control-plane-examples: python3 -m pip install --user jsonschema >/dev/null python3 tools/validate_control_plane_examples.py diff --git a/examples/fit_score.json b/examples/fit_score.json new file mode 100644 index 0000000..44402c4 --- /dev/null +++ b/examples/fit_score.json @@ -0,0 +1,17 @@ +{ + "id": "urn:srcos:fit-score:smelter-audit-0001-r2", + "type": "FitScore", + "specVersion": "2.0.0", + "requestRef": "urn:srcos:labor-request:smelter-audit-0001", + "responseRef": "urn:srcos:labor-response:smelter-audit-0001-r2", + "rubric": { + "domain competence": 0.9, + "independence": 1.0, + "turnaround": 0.8 + }, + "fit": 0.9, + "confidence": 0.85, + "missingEvidence": [ + "conflict-of-interest declaration" + ] +} diff --git a/examples/labor_award.json b/examples/labor_award.json new file mode 100644 index 0000000..be26807 --- /dev/null +++ b/examples/labor_award.json @@ -0,0 +1,31 @@ +{ + "id": "urn:srcos:labor-award:smelter-audit-0001", + "type": "LaborAward", + "specVersion": "2.0.0", + "requestRef": "urn:srcos:labor-request:smelter-audit-0001", + "responseRef": "urn:srcos:labor-response:smelter-audit-0001-r2", + "terms": "Fixed $52k, 3 milestones, independence maintained.", + "paymentModel": "milestone", + "milestones": [ + { + "title": "On-site inspection", + "status": "delivered", + "proofRef": "urn:srcos:attestation:audit/site" + }, + { + "title": "Analysis", + "status": "in_progress" + }, + { + "title": "Signed report", + "status": "pending" + } + ], + "obligations": [ + "maintain independence", + "disclose conflicts" + ], + "trustEventRefs": [ + "urn:srcos:trust-event:eng-coop-completion-01" + ] +} diff --git a/examples/labor_request.json b/examples/labor_request.json new file mode 100644 index 0000000..d3faba0 --- /dev/null +++ b/examples/labor_request.json @@ -0,0 +1,24 @@ +{ + "id": "urn:srcos:labor-request:smelter-audit-0001", + "type": "LaborRequest", + "specVersion": "2.0.0", + "requestType": "review", + "requesterRef": "urn:srcos:party:chuquicamata-smelter", + "objective": "Independent audit of smelter emissions controls before the next regulatory window.", + "outcome": "Signed audit report + remediation punch-list.", + "compensation": { + "transparency": "disclosed", + "model": "fixed", + "minAmount": 40000, + "maxAmount": 60000, + "currency": "USD" + }, + "schedule": "3-week engagement", + "responseDeadline": "2026-07-20T00:00:00Z", + "evaluationCriteria": [ + "domain competence", + "independence", + "turnaround" + ], + "status": "shortlisting" +} diff --git a/examples/labor_response.json b/examples/labor_response.json new file mode 100644 index 0000000..cf7fbfe --- /dev/null +++ b/examples/labor_response.json @@ -0,0 +1,15 @@ +{ + "id": "urn:srcos:labor-response:smelter-audit-0001-r2", + "type": "LaborResponse", + "specVersion": "2.0.0", + "requestRef": "urn:srcos:labor-request:smelter-audit-0001", + "responderRef": "urn:srcos:party:eng-cooperative-4471", + "approach": "Two-auditor team; on-site week 1, analysis week 2, report week 3.", + "terms": "Fixed $52k; independence attested; no prior work for requester.", + "proposedPricing": 52000, + "availability": "starts 2026-07-22", + "evidenceRefs": [ + "urn:srcos:attestation:eng-coop/prior-audits" + ], + "status": "shortlisted" +} diff --git a/examples/trust_event.json b/examples/trust_event.json new file mode 100644 index 0000000..7b08169 --- /dev/null +++ b/examples/trust_event.json @@ -0,0 +1,10 @@ +{ + "id": "urn:srcos:trust-event:eng-coop-completion-01", + "type": "TrustEvent", + "specVersion": "2.0.0", + "subjectRef": "urn:srcos:party:eng-cooperative-4471", + "kind": "completion", + "requestRef": "urn:srcos:labor-request:smelter-audit-0001", + "evidenceRef": "urn:srcos:attestation:audit/site", + "issuedAt": "2026-07-25T00:00:00Z" +} diff --git a/schemas/FitScore.json b/schemas/FitScore.json new file mode 100644 index 0000000..d076174 --- /dev/null +++ b/schemas/FitScore.json @@ -0,0 +1,69 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/FitScore.json", + "title": "FitScore", + "description": "Scores the FIT between a specific request and a specific response. By charter rule the platform scores request↔response fit and MUST NOT publish a universal human-worth / global employability score — hence requestRef AND responseRef are both required and there is no subject-only score.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "requestRef", + "responseRef", + "fit" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:fit-score:", + "description": "Stable URN. Pattern: urn:srcos:fit-score:" + }, + "type": { + "const": "FitScore", + "description": "Discriminator — always \"FitScore\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version, e.g. \"2.0.0\"." + }, + "requestRef": { + "type": "string", + "pattern": "^urn:srcos:labor-request:", + "description": "Required — fit is always request-scoped." + }, + "responseRef": { + "type": "string", + "pattern": "^urn:srcos:labor-response:", + "description": "Required — fit is always response-scoped. No global score exists." + }, + "rubric": { + "type": "object", + "additionalProperties": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "description": "Per-dimension fit (0..1) against the request's evaluation criteria." + }, + "fit": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Overall request↔response fit (0..1)." + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "missingEvidence": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Evidence the reviewer still needs to raise confidence." + } + } +} diff --git a/schemas/LaborAward.json b/schemas/LaborAward.json new file mode 100644 index 0000000..fb24091 --- /dev/null +++ b/schemas/LaborAward.json @@ -0,0 +1,103 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/LaborAward.json", + "title": "LaborAward", + "description": "The accepted working arrangement — records the selected response, terms, milestones, payment model, and obligations, and anchors the work ledger that tracks fulfillment.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "requestRef", + "responseRef", + "terms", + "paymentModel" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:labor-award:", + "description": "Stable URN. Pattern: urn:srcos:labor-award:" + }, + "type": { + "const": "LaborAward", + "description": "Discriminator — always \"LaborAward\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version, e.g. \"2.0.0\"." + }, + "requestRef": { + "type": "string", + "pattern": "^urn:srcos:labor-request:" + }, + "responseRef": { + "type": "string", + "pattern": "^urn:srcos:labor-response:" + }, + "terms": { + "type": "string", + "minLength": 1 + }, + "paymentModel": { + "type": "string", + "enum": [ + "fixed", + "hourly", + "milestone", + "equity", + "stipend" + ] + }, + "milestones": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "title", + "status" + ], + "properties": { + "title": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "in_progress", + "delivered", + "approved", + "disputed" + ] + }, + "proofRef": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "obligations": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Obligations both parties accept." + }, + "trustEventRefs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "pattern": "^urn:srcos:trust-event:" + }, + "description": "Trust events emitted over the life of the award." + } + } +} diff --git a/schemas/LaborRequest.json b/schemas/LaborRequest.json new file mode 100644 index 0000000..b2aadeb --- /dev/null +++ b/schemas/LaborRequest.json @@ -0,0 +1,138 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/LaborRequest.json", + "title": "LaborRequest", + "description": "A structured labor request — the primary unit of the request-and-fulfillment network. NOT a generic post. Every request declares objective, outcome, compensation, schedule, deadline, and evaluation criteria (LN-003); compensation transparency is mandatory except volunteer/mutual-aid/exploratory (LN-004).", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "requestType", + "requesterRef", + "objective", + "outcome", + "compensation", + "responseDeadline", + "evaluationCriteria" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:labor-request:", + "description": "Stable URN. Pattern: urn:srcos:labor-request:" + }, + "type": { + "const": "LaborRequest", + "description": "Discriminator — always \"LaborRequest\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version, e.g. \"2.0.0\"." + }, + "requestType": { + "type": "string", + "enum": [ + "RFI", + "RFP", + "RFQ", + "role", + "collaboration", + "apprenticeship", + "review", + "availability" + ], + "description": "Typed ask: RFI/RFP/RFQ/role/collaboration/apprenticeship/review/availability (LN-002)." + }, + "requesterRef": { + "type": "string", + "description": "The requester (introduces demand)." + }, + "objective": { + "type": "string", + "minLength": 1 + }, + "outcome": { + "type": "string", + "minLength": 1, + "description": "Expected deliverable or outcome." + }, + "compensation": { + "type": "object", + "additionalProperties": false, + "required": [ + "transparency" + ], + "properties": { + "transparency": { + "type": "string", + "enum": [ + "disclosed", + "exempt" + ], + "description": "Compensation SHALL be disclosed except where the request is volunteer, mutual-aid, or exploratory (LN-004)." + }, + "exemptReason": { + "type": "string", + "enum": [ + "volunteer", + "mutual-aid", + "exploratory" + ], + "description": "Required when transparency=exempt." + }, + "model": { + "type": "string", + "enum": [ + "fixed", + "hourly", + "milestone", + "equity", + "stipend" + ] + }, + "minAmount": { + "type": "number", + "minimum": 0 + }, + "maxAmount": { + "type": "number", + "minimum": 0 + }, + "currency": { + "type": "string" + } + } + }, + "schedule": { + "type": [ + "string", + "null" + ], + "description": "Schedule expectations." + }, + "responseDeadline": { + "type": "string", + "description": "ISO-8601 response deadline." + }, + "evaluationCriteria": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "How responses are evaluated (fit, not popularity)." + }, + "status": { + "type": "string", + "enum": [ + "open", + "shortlisting", + "awarded", + "closed", + "withdrawn" + ] + } + } +} diff --git a/schemas/LaborResponse.json b/schemas/LaborResponse.json new file mode 100644 index 0000000..c174a77 --- /dev/null +++ b/schemas/LaborResponse.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/LaborResponse.json", + "title": "LaborResponse", + "description": "A structured response to a LaborRequest — a proposal, quote, expression of interest, or availability signal with evidence. Trial work that produces usable value SHALL be compensated (LN-005).", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "requestRef", + "responderRef", + "approach" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:labor-response:", + "description": "Stable URN. Pattern: urn:srcos:labor-response:" + }, + "type": { + "const": "LaborResponse", + "description": "Discriminator — always \"LaborResponse\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version, e.g. \"2.0.0\"." + }, + "requestRef": { + "type": "string", + "pattern": "^urn:srcos:labor-request:", + "description": "The request this answers." + }, + "responderRef": { + "type": "string", + "description": "The worker/team (introduces supply)." + }, + "approach": { + "type": "string", + "minLength": 1 + }, + "terms": { + "type": [ + "string", + "null" + ] + }, + "proposedPricing": { + "type": [ + "number", + "null" + ], + "minimum": 0 + }, + "availability": { + "type": [ + "string", + "null" + ] + }, + "evidenceRefs": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + }, + "description": "Evidence packets / fulfillment records backing the response — not follower counts." + }, + "status": { + "type": "string", + "enum": [ + "submitted", + "shortlisted", + "declined", + "awarded", + "withdrawn" + ] + } + } +} diff --git a/schemas/TrustEvent.json b/schemas/TrustEvent.json new file mode 100644 index 0000000..8e25376 --- /dev/null +++ b/schemas/TrustEvent.json @@ -0,0 +1,62 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.srcos.ai/v2/TrustEvent.json", + "title": "TrustEvent", + "description": "Updates reputation through an evidenced event tied to a real request/award — reference, verification, completion, dispute, appeal, or correction. The reputation primitive is fulfillment history, not follower counts.", + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "type", + "specVersion", + "subjectRef", + "kind" + ], + "properties": { + "id": { + "type": "string", + "pattern": "^urn:srcos:trust-event:", + "description": "Stable URN. Pattern: urn:srcos:trust-event:" + }, + "type": { + "const": "TrustEvent", + "description": "Discriminator — always \"TrustEvent\"." + }, + "specVersion": { + "type": "string", + "description": "Spec version, e.g. \"2.0.0\"." + }, + "subjectRef": { + "type": "string", + "description": "The party whose fulfillment history this updates." + }, + "kind": { + "type": "string", + "enum": [ + "reference", + "verification", + "completion", + "dispute", + "appeal", + "correction" + ] + }, + "requestRef": { + "type": [ + "string", + "null" + ], + "pattern": "^urn:srcos:labor-request:", + "description": "The request/award this event is tied to — reputation is fulfillment-anchored." + }, + "evidenceRef": { + "type": [ + "string", + "null" + ] + }, + "issuedAt": { + "type": "string" + } + } +} diff --git a/tools/validate_labor_market_examples.py b/tools/validate_labor_market_examples.py new file mode 100644 index 0000000..25b357a --- /dev/null +++ b/tools/validate_labor_market_examples.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +"""Validate the request-centric labor-market contract examples. + +Labor is modeled as request + response + evidence + fulfillment + trust — NOT +identity + feed + attention. Covers LaborRequest (the structured ask), +LaborResponse (the proposal), FitScore (request<->response fit; never a global +human-worth score), LaborAward (the accepted arrangement + work ledger), and +TrustEvent (reputation from evidenced fulfillment). +""" +from __future__ import annotations + +import json +from pathlib import Path + +import jsonschema + +ROOT = Path(__file__).resolve().parents[1] +PAIRS = [ + (ROOT / "schemas" / "LaborRequest.json", ROOT / "examples" / "labor_request.json"), + (ROOT / "schemas" / "LaborResponse.json", ROOT / "examples" / "labor_response.json"), + (ROOT / "schemas" / "FitScore.json", ROOT / "examples" / "fit_score.json"), + (ROOT / "schemas" / "LaborAward.json", ROOT / "examples" / "labor_award.json"), + (ROOT / "schemas" / "TrustEvent.json", ROOT / "examples" / "trust_event.json"), +] + + +def validate_pair(schema_path: Path, example_path: Path) -> None: + schema = json.loads(schema_path.read_text(encoding="utf-8")) + jsonschema.validators.validator_for(schema).check_schema(schema) + example = json.loads(example_path.read_text(encoding="utf-8")) + jsonschema.validate(example, schema) + + +def main() -> int: + checks: dict[str, bool] = {} + for schema_path, example_path in PAIRS: + validate_pair(schema_path, example_path) + checks[example_path.name] = True + print(json.dumps({"ok": all(checks.values()), "checks": checks}, indent=2, sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())