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.
| Path | Type | Required | Description | Constraints | Stability |
|---|---|---|---|---|---|
schema_version | string | yes | Contract 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 |
timestamp | string | yes | ISO 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_id | string | yes | SHA-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_type | string | yes | CLOSED, 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_tier | integer | yes | one of 1, 2, 3, 4max 9007199254740991 | stable | |
spec_slug | string | stable | |||
phase | string | An 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_agent | string | stable | |||
model_vendor | string | stable | |||
model_family | string | stable | |||
model_version | string | stable | |||
prompt_hash | string | SHA-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 | |
outcome | string | one of "success", "failure", "partial" | stable | ||
details | object | Flat 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 |