CDF CDI signal

One line of the append-only Cognitive Delivery Index signal log. The Index is computed entirely from these plus the governed artefacts on disk, which is why it is domain-neutral: no code, no language, no build and no test appears anywhere in its inputs. Two products writing these differently is the failure this contract exists to prevent.

Schema
cdi-signal.schema.json, served as JSON at its $id: https://cognitive-delivery.github.io/contract/1.x/cdi-signal.schema.json
Dialect
http://json-schema.org/draft-07/schema#
Root
object, open (additional properties are carried)
required: schema_version, timestamp, workspace_id, event_type, adoption_tier
Stability
none stated at the root; every declared property carries its own
Properties
14 declared: 14 under the root, 0 in definitions

Properties

Every declared property under the root, in the schema's own order. [] is an array's items, .* the shape of every unnamed member, #name a definition. Objects carry additional properties unless a row says otherwise.

PathTypeRequiredDescriptionConstraintsStability
schema_versionstringyesContract version this record was written against, as major.minor. One rule across every schema (schema set 1.2): a reader compares the major only, and a minor it has not met is additive by the contract's own rule.pattern ^\d+\.\d+$stable
timestampstringyesISO 8601 with a timezone.pattern ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$stable
workspace_idstringyesSHA-256 of the git remote URL, lower-case hex, when the workspace has a remote; otherwise a per-checkout lower-case UUID the collector generates and stores under .cdf/. Never a person identifier and not reversible to one. CORRECTED against real artefacts: the earlier description claimed the hash form only, while 4,910 of 5,634 signals in the reference deployment carry the UUID form.any of: (1) pattern ^[0-9a-f]{64}$; (2) pattern ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$stable
event_typestringyesCLOSED, unlike the audit journal's event_type. The Index is computed from this vocabulary, so a second product adding a value is a contract change and should be one. Governed by ADR-013.one of 127 values
all 127"workspace.initialised", "workspace.onboarding_route_selected", "workspace.onboarding_preview_generated", "workspace.onboarding_import_applied", "workspace.onboarding_skipped", "workspace.onboarding_agent_briefed", "work.intake_classified", "spec.created", "artefact.recorded", "artefact.written", "artefact.structure_invalid", "artefact.lint_completed", "task.status_updated", "execution.plan_created", "execution.task_claimed", "decision.evidence_checked", "decision.record_created", "decision.record_linked", "cdi.assessment_recorded", "phase.advanced", "phase.reverted", "phase.gate_failed", "review.recorded", "adoption_tier.changed", "break_glass.used", "break_glass.reverted", "mode.switched", "mode.switch_refused", "tool.call_refused", "ux.surface_consolidation_applied", "setup.completed", "setup.abandoned", "plane.connected", "plane.disconnected", "plane.unreachable", "plane.policy_malformed", "plane.policy_overrode_local", "plane.evidence_replicated", "plane.evidence_drop", "plane.evidence_drop_batch", "plane.auth_failed", "plane.seat_revoked", "governance.synced", "governance.seal_applied", "governance.source_unreachable", "provenance.drift_detected", "hook.executed", "hook.failed", "migration.kiro_planned", "migration.kiro_applied", "migration.kiro_failed", "migration.fg_enabled_to_mode", "integration.previewed", "integration.action_requested", "integration.action_succeeded", "integration.action_failed", "integration.health_checked", "integration.gate_evidence_checked", "fg.dispatch.previewed", "fg.dispatch.confirmed", "fg.dispatch.started", "fg.dispatch.completed", "fg.dispatch.failed", "fg.dispatch.cancelled", "fg.dispatch.expired", "fg.proposal.created", "fg.proposal.accepted", "fg.proposal.rejected", "fg.proposal.archived", "fg.proposal.superseded", "fg.proposal.converted", "fg.comparison.created", "fg.comparison.synthesis_created", "fg.integration.previewed", "fg.integration.confirmation_required", "fg.integration.result_recorded", "fg.integration.evidence_checked", "fg.orchestration.planned", "fg.orchestration.started", "fg.orchestration.worker_updated", "fg.orchestration.completed", "fg.orchestration.cancelled", "fg.orchestration.degraded", "session.started", "session.ended", "config.drift_detected", "spec.archived", "spec.deleted", "work.tool_invoked", "work.worktree_lifecycle", "chat.turn_started", "chat.turn_completed", "work.code_map_generated", "work.verification_run", "work.handoff_generated", "work.session_resumed", "work.impact_computed", "governance.ledger_sealed", "governance.ledger_verified", "governance.compliance_exported", "work.journal_generated", "work.journal_note_written", "work.journal_read", "governance.attestation_generated", "knowledge.graph_built", "knowledge.graph_queried", "governance.guardrail_promoted", "memory.captured", "memory.approved", "memory.lesson_recorded", "memory.rejected", "delivery.metrics_computed", "agent.trajectory_analyzed", "approval.calibrated", "nondev.prd_translated", "disclosure.evaluated", "diagram.generated", "fleet.enforcement_exported", "safety.scan_completed", "safety.budget_exceeded", "polyglot.scanned", "architecture.currency_assessed", "architecture.currency_snapshot_saved", "architecture.insight_discussed", "deploy.strategy_discussed", "deploy.assurance_report_generated", "deploy.assurance_signoff_recorded"
stable
adoption_tierintegeryesone of 1, 2, 3, 4
max 9007199254740991
stable
spec_slugstringstable
phasestringAn OPEN string, for the same reason as on the audit event. A reader must tolerate an unrecognised value: not throw, not coerce, not drop.stable
runtime_agentstringstable
model_vendorstringstable
model_familystringstable
model_versionstringstable
prompt_hashstringSHA-256 of the prompt, lower-case hex. NEVER the prompt itself; the pattern refuses anything that is not a 64-character digest.pattern ^[0-9a-f]{64}$stable
outcomestringone of "success", "failure", "partial"stable
detailsobjectFlat scalars only, and keys are filtered by name as on the audit event: a key with a lower-case or camelCase segment that is authorization, content, file, password, path, payload, prompt, request, secret or token is refused, which approximates the reference writer's rule (propertyNames lists the differences). Must never contain secrets, personal data or file contents.keys must not match (^|[^A-Za-z0-9])(authorization|content|file|password|path|payload|prompt|request|secret|token)([^A-Za-z0-9]|$)
keys must not match [a-z0-9](Authorization|Content|File|Password|Path|Payload|Prompt|Request|Secret|Token)([^a-z]|$)
keys must not match ^(authorization|content|file|password|path|payload|prompt|request|secret|token)[A-Z]
Approximates the reference writer's rule, which splits a key at camelCase boundaries, lower-cases it, splits it on non-alphanumerics and drops it when any segment is one of ten words: authorization, content, file, password, path, payload, prompt, request, secret, token. The three clauses refuse the lower-case segment form (api_token, file-path), the camelCase interior form (filePath, apiToken) and the camelCase leading form (tokenCount). The differences: the schema is case-sensitive, so it admits Authorization, API_TOKEN, Token, TokenCount, PATH and x-Token, all of which the writer drops; and it ends a camelCase segment at a digit, so it refuses apiToken2 and myFile2, which the writer keeps. estimated_files_touched is legal: files is not file. No lookahead, so RE2 validators load it.
additional properties: see details.*
stable
details.*string | number | boolean