Overview
CocoTrace maintains a directed dependency graph: bloom.md → discuss.md → spec.md → plan.md → build-output → eval-results. SHA-256 content hashes detect genuine changes (not timestamp drift from git operations). Staleness propagates downstream from any changed node.
Why SHA-256, not timestamps: Rebase and cherry-pick change file mtimes without changing content. SHA-256 only signals real changes.
Commands
$trace build
- Execute the
cocotrace/trace-checkcontract (deterministic, no LLM, Tier 2 async) - Read output
lifecycle/trace.json - Display summary table:
Artifact Status SHA-256
────────────── ──────── ──────────
bloom.md current abc12345
discuss.md stale def67890
spec.md stale (downstream of discuss.md)
plan.md missing —
build-output missing —
eval-results missing —
- Create git commit:
chore(cocotrace): update artifact traceability graph - Output: "[N] current, [M] stale, [P] missing"
Idempotent: Running twice on unchanged content produces bit-identical trace.json.
$trace gaps
-
Read
lifecycle/trace.json -
Read
lifecycle/spec.md- If spec.md has no
##section headings: output "spec.md has no section structure — gap analysis requires structured sections" and exit gracefully
- If spec.md has no
-
Extract requirement sections (all
##headings in spec.md) -
Check
lifecycle/build/for corresponding implementation files -
Report:
## Traceability Gap Analysis ### Orphaned Requirements (in spec.md, no build artifact) - § 3.2 Model Selection Criteria — no matching build artifact found ### Uncovered Code (in build/, no traceable requirement) - lifecycle/build/helper-utils.sql — not referenced in spec.md ### Coverage Requirements covered: 4/6 (67%) Implementation traced: 3/4 (75%)
$trace show <artifact>
-
Read
lifecycle/trace.json -
Trace backward from
<artifact>: which upstream nodes inform it? -
Trace forward: which downstream nodes it produces?
-
Display ASCII dependency chain with YOU ARE HERE marker:
bloom.md [current] └── discuss.md [current] └── spec.md [← YOU ARE HERE] [current] └── plan.md [stale] └── build-output [missing] └── eval-results [missing]
$trace blast <object>
Computes the blast radius for a named Snowflake object (table, view, column, or Cortex model identifier) — all Cortex functions in the CocoPod that depend on it.
-
Execute the
cocotrace/trace-blastcontract for<object>. It readssnowflake-deps.json(the reverse index of function → object dependencies, maintained by$trace sync) and returns every function that depends on<object>. -
For each affected function, report the dependency type (
read,write, orstructural), the downstream traceability chain to its CocoBloom commitment and CocoSpec outcome statement, and whether its CocoContract evidence is stale relative to the object's current state. -
Display:
## Blast Radius: customer_events (table) | Function | Dependency | Chain | Contract Evidence | |------------------------|-----------|-------------------------------------------|--------------------| | classify_sentiment | read | bloom → spec § 2.1 → build/classify.sql | STALE — reprove required | | enrich_customer_profile| write | bloom → spec § 3.4 → build/enrich.sql | current | 2 functions affected. 1 requires CocoContract re-proof after this change.
snowflake-deps.json is committed to the CocoPod repository and updated by $trace sync whenever a build artifact changes — it records, per function, the objects read, the objects written, and the Cortex API features depended on.
$trace check --before-change "<change description>"
A pre-change impact gate, not a permission gate — it does not block the change. Runs the blast radius computation for the objects implied by <change description>, generates a human-readable impact summary, and records the gate event in lifecycle/audit.md via CocoAudit (proving blast radius was assessed before the change was applied). Output the same blast radius table as $trace blast, prefixed with the change description and an audit confirmation line: "Recorded to lifecycle/audit.md as a pre-change impact assessment."
$trace health
Compute the Snowflake asset health grade for the current dependency graph. Run:
invoke cocotrace/health-grader --input .cocoplus/trace/snowflake-assets.json
The grade is A-F and combines dead asset percentage, circular dependencies, coupling, security findings, layer violations, and churn hotspots. Dead assets include zero-caller UDFs, unqueried views, and stale tables. Layer violations include staging objects consumed directly by BI, raw sources updated by application code, and production assets accessed from development contexts.
If [trace].show_grade = false in cocoplus.toml, suppress the letter grade but still show the underlying metrics.
$trace compare <before.json> <after.json>
Run:
invoke cocotrace/health-grader --compare <before.json> <after.json>
Display the thermal receipt line exactly as a before/after delta, for example:
blast radius 23 -> 18 v / health B+ -> A- ^
SessionStart Integration
SessionStart appends a cocotrace/trace-check request (Tier 2 async — non-blocking). If any artifact is stale, a non-blocking advisory appears:
⚠️ CocoTrace: discuss.md changed since spec.md was last traced.
Run `$trace build` to update the traceability graph.
Key Constraints
cocotrace/trace-checkis DETERMINISTIC — no LLM, no inference- SHA-256 computed from file CONTENT, not metadata
trace.jsonrecords git branch and commit metadata for the trace run- Staleness propagates in
walk_order— downstream always stale if upstream changed - SessionStart advisory is NON-BLOCKING — never prevents session start
lifecycle/trace.jsoncommitted to git — team-visible
Git Behavior
lifecycle/trace.json committed after $trace build: chore(cocotrace): update artifact traceability graph
Export
Trace reports such as trace-gaps.md or blast-radius summaries can be exported through the shared exporter:
invoke reporting/report-export --source <trace-report.md> --format <markdown|html|pdf> --out-dir .cocoplus/trace/exports
PDF requests report renderer availability; Markdown and HTML are local deterministic exports.
Exit Criteria
-
$trace buildproduces identicaltrace.jsonon two consecutive runs with no file changes -
trace.jsonincludes the git branch and commit SHA observed during the trace run - Modifying
bloom.mdcausesdiscuss.md,spec.md,plan.mdto showstale -
$trace gapshandles missing section headings gracefully - SessionStart surfaces staleness advisory non-blockingly
-
$trace blast <object>returns affected functions with dependency type and CocoContract staleness flag, sourced fromsnowflake-deps.json -
$trace check --before-changerecords the gate event tolifecycle/audit.mdwithout blocking the change -
$trace healthreports grade inputs and honors[trace].show_grade = false -
$trace compareprints blast-radius and health-grade before/after deltas
Anti-Rationalization
| Temptation | Why Wrong |
|---|---|
| Use file timestamps | Timestamps change on git operations without content change — SHA-256 only |
| Mark only the changed node stale | Downstream must also be stale — requirement traceability demands it |
| Block SessionStart until trace runs | Tier 2 async — never blocks the developer prompt |
| Re-run LLM to validate staleness | Staleness is a content-hash comparison — deterministic, no LLM needed |