Skip to content

feat(sparkctl): add SPARK Evidence Packet v1#3

Merged
ProfRandom92 merged 3 commits into
mainfrom
spark-evidence-packet-v1
Jun 7, 2026
Merged

feat(sparkctl): add SPARK Evidence Packet v1#3
ProfRandom92 merged 3 commits into
mainfrom
spark-evidence-packet-v1

Conversation

@ProfRandom92
Copy link
Copy Markdown
Owner

@ProfRandom92 ProfRandom92 commented Jun 7, 2026

Summary

Adds SPARK Evidence Packet v1 as a local deterministic evidence packet for sparkctl.

This branch introduces a typed packet preimage/envelope model, canonical JSON generation from the preimage, a SHA-256 hash over that canonical JSON, CLI demo and validation commands, docs for artifact/claim boundaries, and committed agent instructions for review-safe work.

What Changed

  • Added SparkEvidencePacketPreimage and SparkEvidencePacketEnvelope.
  • Added policy, provider-boundary, human-review, claim-hygiene, and artifact-manifest fields.
  • Computes canonical_json from preimage fields only.
  • Computes canonical_hash as SHA-256 over canonical_json.
  • Adds sparkctl spark-evidence-demo.
  • Adds sparkctl spark-evidence-validate.
  • Adds packet validation for stale preimage, stale canonical JSON, stale hash, and missing required fields.
  • Adds SPARK alignment, safety/claims, artifact contract, implementation report, README update proposal, and handoff docs.
  • AGENTS.md and .agents/skills/** are intentional review/governance instructions for this repository.

Boundaries

  • Provider output remains untrusted until human review.
  • Human review remains the approval boundary.
  • Goal does not bypass Policy Gate, Provider Boundary, or Human Review.
  • This is a local deterministic evidence packet / review-gated workflow artifact.
  • No production readiness, compliance, legal evidentiary, forensic certainty, official SPARK compatibility, or autonomous approval claim is made.
  • Root README.md was not modified.
  • Generated report churn was excluded.

Validation

  • cargo fmt --all --check: PASS
  • cargo test: PASS
  • cargo clippy --all-targets --all-features -- -D warnings: PASS
  • cargo run --bin sparkctl -- spark-evidence-validate --input ../artifacts/spark/evidence_packet_v1.json: PASS

CI

  • Rust Validation CI / validate: SUCCESS on PR head 1623a3ae591ed50fd34c3dae38db0375e3dd2ca0.
  • Local validation passed before push:
    • cargo fmt --all --check
    • cargo test
    • cargo clippy --all-targets --all-features -- -D warnings
    • cargo run --bin sparkctl -- spark-evidence-validate --input ../artifacts/spark/evidence_packet_v1.json

Reviewer Checklist

  • Confirm canonical JSON is derived only from packet preimage fields.
  • Confirm canonical_hash is SHA-256 over canonical JSON.
  • Confirm packet validation rejects stale/tampered preimage, canonical JSON, and hash.
  • Confirm .spkg package compatibility is preserved.
  • Confirm provider output is still represented as untrusted.
  • Confirm Policy Gate, Provider Boundary, and Human Review are not bypassed.
  • Confirm docs avoid production, compliance, legal, forensic, official compatibility, and autonomous approval claims.
  • Confirm generated report churn is not included in the PR.
  • Confirm no provider calls, GitHub writes, deploy hooks, tokens, or secrets are added.

Risks

  • cargo test can generate local report churn in reports/latest.json and reports/performance_baseline.json; those files are excluded from this branch.
  • Artifact manifest paths use relative ../... entries, so reviewers should confirm the intended base path is clear enough for downstream users.
  • The packet is a bounded demo/prototype artifact and does not represent external review state.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the SPARK Evidence Packet v1, introducing a deterministic, reviewable evidence envelope along with CLI commands, comprehensive unit tests, agent skill guidelines, and detailed documentation. The code review feedback focuses on enhancing security and robustness by enforcing strict schema validation (deny_unknown_fields), validating that list elements are not empty or whitespace-only, and improving error handling for missing files. Additionally, the feedback suggests optimizing JSON deserialization to avoid unnecessary cloning, simplifying directory creation, and renaming enum variants to adhere to Rust naming conventions.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread agy7rust/src/codec/package.rs
Comment thread agy7rust/src/codec/package.rs Outdated
Comment thread agy7rust/src/sparkctl/spark_evidence.rs Outdated
Comment thread agy7rust/src/sparkctl/spark_evidence.rs
Comment on lines +5 to +13
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PolicyResult {
#[serde(rename = "ALLOW")]
ALLOW,
#[serde(rename = "REVIEW_NEEDED")]
ReviewNeeded,
#[serde(rename = "BLOCK")]
BLOCK,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the Rust API Guidelines (C-CASE), enum variants should use UpperCamelCase (PascalCase).

Renaming ALLOW and BLOCK to Allow and Block adheres to this standard. Since #[serde(rename = "...")] is already used, this change will not affect the serialized JSON representation.

Suggested change
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PolicyResult {
#[serde(rename = "ALLOW")]
ALLOW,
#[serde(rename = "REVIEW_NEEDED")]
ReviewNeeded,
#[serde(rename = "BLOCK")]
BLOCK,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PolicyResult {
#[serde(rename = "ALLOW")]
Allow,
#[serde(rename = "REVIEW_NEEDED")]
ReviewNeeded,
#[serde(rename = "BLOCK")]
Block,
}
References
  1. Rust naming conventions (C-CASE) dictate that enum variants should be in UpperCamelCase (PascalCase). (link)

Comment on lines +15 to +25
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ProviderBoundaryStatus {
#[serde(rename = "DEMO")]
DEMO,
#[serde(rename = "UNAVAILABLE")]
UNAVAILABLE,
#[serde(rename = "AVAILABLE")]
AVAILABLE,
#[serde(rename = "BLOCKED_BY_POLICY")]
BlockedByPolicy,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the Rust API Guidelines (C-CASE), enum variants should use UpperCamelCase (PascalCase).

Renaming DEMO, UNAVAILABLE, and AVAILABLE to Demo, Unavailable, and Available adheres to this standard.

Suggested change
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ProviderBoundaryStatus {
#[serde(rename = "DEMO")]
DEMO,
#[serde(rename = "UNAVAILABLE")]
UNAVAILABLE,
#[serde(rename = "AVAILABLE")]
AVAILABLE,
#[serde(rename = "BLOCKED_BY_POLICY")]
BlockedByPolicy,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ProviderBoundaryStatus {
#[serde(rename = "DEMO")]
Demo,
#[serde(rename = "UNAVAILABLE")]
Unavailable,
#[serde(rename = "AVAILABLE")]
Available,
#[serde(rename = "BLOCKED_BY_POLICY")]
BlockedByPolicy,
}
References
  1. Rust naming conventions (C-CASE) dictate that enum variants should be in UpperCamelCase (PascalCase). (link)

Comment on lines +27 to +35
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum HumanReviewDecision {
#[serde(rename = "PASS")]
PASS,
#[serde(rename = "NOTES")]
NOTES,
#[serde(rename = "BLOCKED")]
BLOCKED,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the Rust API Guidelines (C-CASE), enum variants should use UpperCamelCase (PascalCase).

Renaming PASS, NOTES, and BLOCKED to Pass, Notes, and Blocked adheres to this standard.

Suggested change
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum HumanReviewDecision {
#[serde(rename = "PASS")]
PASS,
#[serde(rename = "NOTES")]
NOTES,
#[serde(rename = "BLOCKED")]
BLOCKED,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum HumanReviewDecision {
#[serde(rename = "PASS")]
Pass,
#[serde(rename = "NOTES")]
Notes,
#[serde(rename = "BLOCKED")]
Blocked,
}
References
  1. Rust naming conventions (C-CASE) dictate that enum variants should be in UpperCamelCase (PascalCase). (link)

Comment on lines +134 to +137
pub fn validate_spark_evidence_packet_value(value: &serde_json::Value) -> anyhow::Result<()> {
let envelope: SparkEvidencePacketEnvelope = serde_json::from_value(value.clone())?;
validate_spark_evidence_packet_envelope(&envelope)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of cloning the serde_json::Value to deserialize it, you can deserialize directly from the reference value because serde_json::Value implements serde::Deserializer. This avoids unnecessary allocations and cloning of the JSON tree.

Suggested change
pub fn validate_spark_evidence_packet_value(value: &serde_json::Value) -> anyhow::Result<()> {
let envelope: SparkEvidencePacketEnvelope = serde_json::from_value(value.clone())?;
validate_spark_evidence_packet_envelope(&envelope)
}
pub fn validate_spark_evidence_packet_value(value: &serde_json::Value) -> anyhow::Result<()> {
let envelope = SparkEvidencePacketEnvelope::deserialize(value)?;
validate_spark_evidence_packet_envelope(&envelope)
}

@ProfRandom92 ProfRandom92 merged commit c9a7dec into main Jun 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant