Skip to content

Fix review feedback: shared type aliases, Z timestamp, vocabulary validation, ValueError masking#320

Merged
ahouseholder merged 2 commits intotrigger-endpointsfrom
copilot/sub-pr-319
Mar 10, 2026
Merged

Fix review feedback: shared type aliases, Z timestamp, vocabulary validation, ValueError masking#320
ahouseholder merged 2 commits intotrigger-endpointsfrom
copilot/sub-pr-319

Conversation

Copy link
Contributor

Copilot AI commented Mar 10, 2026

Addresses all review comments from PR #319. Consolidates non-empty string validation into shared type aliases, fixes ISO-8601 Z parsing, enforces tag vocabulary membership, and eliminates a silent error-masking pattern.

Changes

Shared NonEmptyString / OptionalNonEmptyString type aliases (vultron/as_vocab/base/types.py)

  • New module with NonEmptyString = Annotated[str, AfterValidator(_non_empty)] and OptionalNonEmptyString = Optional[NonEmptyString]
  • Validator rejects empty and whitespace-only strings; implements CS-08-002

VulnerabilityRecord and EmbargoPolicy refactored

  • Replaced per-field @field_validator stubs with shared type aliases on name, aliases, actor_id, inbox, notes
  • Tests updated to assert "must be a non-empty string" (Pydantic includes field path in full error output)

CaseEvent — ISO-8601 Z suffix support

  • parse_received_at() now normalizes Z+00:00 before fromisoformat(), works across all Python versions
# Before: fails on "2026-03-06T20:00:00Z" in Python < 3.11
return datetime.fromisoformat(v)
# After: always works
return datetime.fromisoformat(v.replace("Z", "+00:00"))

CreateInitialVendorParticipant — eliminate ValueError masking

  • Replaced try/except ValueError around datalayer.create() with an explicit datalayer.read() pre-check
  • The old pattern silently swallowed ValueError for wrong record type or missing id_; now only skips creation when the record already exists

CaseReference — enforce tag vocabulary

  • validate_tags() now validates each tag against CASE_REFERENCE_TAG_VOCABULARY; previously the constant was defined but never used
  • Invalid tags raise ValueError with the full list of valid options

prompts/IDEATION_prompt.md

  • Fixed broken path: plans/IDEAS.mdplan/IDEAS.md (two occurrences)

Please note: Pull request submissions are subject to our
Contribution Instructions


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

@ahouseholder
Copy link
Contributor

Also be sure to fix markdownlint issues

…bulary validation, ValueError masking, broken path

Co-authored-by: ahouseholder <2594236+ahouseholder@users.noreply.github.com>
Copilot AI changed the title [WIP] Add triggerable endpoints for Vultron interactions Fix review feedback: shared type aliases, Z timestamp, vocabulary validation, ValueError masking Mar 10, 2026
@ahouseholder ahouseholder marked this pull request as ready for review March 10, 2026 17:05
@ahouseholder ahouseholder self-requested a review as a code owner March 10, 2026 17:05
Copilot AI review requested due to automatic review settings March 10, 2026 17:05
@ahouseholder ahouseholder merged commit 463fbb9 into trigger-endpoints Mar 10, 2026
5 checks passed
@ahouseholder ahouseholder deleted the copilot/sub-pr-319 branch March 10, 2026 17:11
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses review feedback from PR #319 by consolidating non-empty string validation into shared type aliases, fixing ISO-8601 Z parsing for timestamps, enforcing tag vocabulary membership in CaseReference, eliminating a silent ValueError-masking pattern, and fixing a broken file path in a prompt.

Changes:

  • New NonEmptyString/OptionalNonEmptyString type aliases in vultron/as_vocab/base/types.py (per CS-08-002), replacing per-field validators in VulnerabilityRecord and EmbargoPolicy
  • CaseEvent now handles ISO-8601 Z UTC suffix in received_at string parsing; CaseReference.validate_tags() now enforces membership in CASE_REFERENCE_TAG_VOCABULARY; CreateInitialVendorParticipant replaces try/except ValueError with explicit datalayer.read() pre-check
  • Path correction in prompts/IDEATION_prompt.md: plans/IDEAS.mdplan/IDEAS.md

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
vultron/as_vocab/base/types.py New module defining shared NonEmptyString and OptionalNonEmptyString Pydantic type aliases per CS-08-002
vultron/as_vocab/objects/vulnerability_record.py Replaces per-field validators with NonEmptyString/list[NonEmptyString] type aliases
vultron/as_vocab/objects/embargo_policy.py Replaces per-field validators with NonEmptyString/OptionalNonEmptyString type aliases
vultron/as_vocab/objects/case_event.py Fixes Z-suffix ISO-8601 parsing by normalizing before fromisoformat()
vultron/as_vocab/objects/case_reference.py Enforces tag vocabulary membership in the existing validate_tags() validator
vultron/behaviors/case/nodes.py Replaces silent ValueError swallowing with explicit pre-check via datalayer.read()
test/as_vocab/test_vulnerability_record.py Updates error message assertions to match the new shared validator message
test/as_vocab/test_embargo_policy.py Updates error message assertions to match the new shared validator message
test/as_vocab/test_case_reference.py Adds test for invalid tag vocabulary rejection
test/as_vocab/test_case_event.py Adds test for Z-suffix ISO-8601 parsing
prompts/IDEATION_prompt.md Fixes two broken path references plans/IDEAS.mdplan/IDEAS.md

def parse_received_at(cls, v) -> datetime:
if isinstance(v, str):
return datetime.fromisoformat(v)
return datetime.fromisoformat(v.replace("Z", "+00:00"))
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

The str.replace("Z", "+00:00") call replaces ALL occurrences of "Z" in the input string, not just a trailing one. While a well-formed ISO 8601 timestamp only has "Z" as a trailing UTC designator (so in practice this is harmless), a more precise and defensive implementation would only replace a trailing "Z". For example, checking v.endswith("Z") before replacing, or using a targeted replacement like (v[:-1] + "+00:00") if v.endswith("Z") else v.

Suggested change
return datetime.fromisoformat(v.replace("Z", "+00:00"))
if v.endswith("Z"):
v = v[:-1] + "+00:00"
return datetime.fromisoformat(v)

Copilot uses AI. Check for mistakes.
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.

3 participants