Skip to content

fix(scripts): standardize Timestamp JSON key casing across all lint result files#1314

Open
chaosdinosaur wants to merge 14 commits intomainfrom
fix/1003-standardize-timestamp-key-casing
Open

fix(scripts): standardize Timestamp JSON key casing across all lint result files#1314
chaosdinosaur wants to merge 14 commits intomainfrom
fix/1003-standardize-timestamp-key-casing

Conversation

@chaosdinosaur
Copy link
Copy Markdown
Collaborator

@chaosdinosaur chaosdinosaur commented Apr 7, 2026

Pull Request

Description

Standardizes the timestamp JSON key casing to Timestamp (capital T) across the four remaining linting scripts and their corresponding Pester test files. Issues #994#1002 previously standardized the other scripts; this PR completes the final batch for issue #1003.

The change ensures every lint result JSON file uses Timestamp = Get-StandardTimestamp with consistent PascalCase key naming, matching the convention established by Get-StandardTimestamp in LintingHelpers.psm1.

Fixes #1003

Related Issue(s)

Fixes #1003

Type of Change

Select all that apply:

Code & Documentation:

  • Bug fix (non-breaking change fixing an issue)

Other:

  • Script/automation (.ps1, .sh, .py)

Testing

Files Changed

Scripts (hashtable key timestampTimestamp):

  • scripts/linting/Invoke-LinkLanguageCheck.ps1 — lines 87, 141
  • scripts/linting/Markdown-Link-Check.ps1 — line 322
  • scripts/linting/Test-CopyrightHeaders.ps1 — line 242
  • scripts/linting/Validate-SkillStructure.ps1 — line 494

Tests (assertions updated to match new casing):

  • scripts/tests/linting/Invoke-LinkLanguageCheck.Tests.ps1 — lines 133, 187
  • scripts/tests/linting/Markdown-Link-Check.Tests.ps1 — line 352
  • scripts/tests/linting/Test-CopyrightHeaders.Tests.ps1 — lines 594, 603
  • scripts/tests/linting/Validate-SkillStructure.Tests.ps1 — line 827

Checklist

Required Checks

  • Documentation is updated (if applicable)
  • Files follow existing naming conventions
  • Changes are backwards compatible (if applicable)
  • Tests added for new functionality (if applicable)

Required Automated Checks

  • Markdown linting: npm run lint:md
  • PowerShell analysis: npm run lint:ps
  • Spell checking: npm run spell-check — N/A, no prose changes; verified pass
  • Frontmatter validation: npm run lint:frontmatter — N/A, no markdown frontmatter changes; verified pass
  • Skill structure validation: npm run validate:skills — N/A, no skill changes; verified pass (17 skills, 0 errors)
  • Link validation: npm run lint:md-links — N/A, no markdown changes; verified pass
  • Plugin freshness: npm run plugin:generate — N/A, no plugin-affecting changes
  • Docusaurus tests: npm run docs:test — N/A, no documentation changes

Security Considerations

  • This PR does not contain any sensitive or NDA information
  • Any new dependencies have been reviewed for security issues
  • Security-related scripts follow the principle of least privilege

Additional Notes

Three additional scripts (Test-ActionVersionConsistency.ps1, Test-SHAStaleness.ps1, Invoke-PesterTests.ps1) use inline [datetime]::UtcNow instead of Get-StandardTimestamp and were intentionally left out of this PR per user direction. They may warrant separate issues to adopt Get-StandardTimestamp."

@chaosdinosaur chaosdinosaur requested a review from a team as a code owner April 7, 2026 22:23
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.65%. Comparing base (ef520df) to head (e6f7957).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1314      +/-   ##
==========================================
- Coverage   87.66%   87.65%   -0.02%     
==========================================
  Files          61       61              
  Lines        9328     9328              
==========================================
- Hits         8177     8176       -1     
- Misses       1151     1152       +1     
Flag Coverage Δ
pester 85.22% <100.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
scripts/linting/Invoke-LinkLanguageCheck.ps1 87.67% <100.00%> (ø)
scripts/linting/Markdown-Link-Check.ps1 57.51% <100.00%> (ø)
scripts/linting/Test-CopyrightHeaders.ps1 90.09% <100.00%> (ø)
scripts/linting/Validate-SkillStructure.ps1 94.46% <100.00%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Review Summary

This PR makes the right change — renaming the remaining lowercase timestamp JSON keys to Timestamp (PascalCase) to match the convention already enforced by Get-StandardTimestamp in LintingHelpers.psm1. The core logic is correct, all four script hashtables and their corresponding test assertions are consistently updated, and no security or functional concerns were found.

However, there are a few items that must be addressed before this can merge.


Issue Alignment

Fixes #1003 — the PR correctly addresses the stated goal of standardizing Timestamp casing.

📌 Scope observation (non-blocking): Issue #1003's "Files Requiring Changes" table listed two files (Invoke-LinkLanguageCheck.ps1 and Markdown-Link-Check.ps1), but the PR also updates Test-CopyrightHeaders.ps1 and Validate-SkillStructure.ps1. This is the right call — those two files had the same inconsistency and should be fixed here. The PR description acknowledges this, and the additional changes are well-scoped and correct. No action needed; just confirming the intentional expansion aligns with the issue's underlying goal.


PR Template Compliance

⚠️ Several required automated checks are absent from the PR description. The template's "Required Automated Checks" section lists eight commands that must pass before merging. The PR only records two of them (lint:md and lint:ps). The following six are missing entirely:

Command Expected disposition for this PR
npm run spell-check Run and confirm pass (or mark N/A if no prose changed)
npm run lint:frontmatter Run and confirm pass (or mark N/A)
npm run validate:skills Run and confirm pass (or mark N/A)
npm run lint:md-links Run and confirm pass (or mark N/A)
npm run plugin:generate Run and confirm pass (or mark N/A)
npm run docs:test Run and confirm pass (or mark N/A)

Even when a command is not expected to surface failures for a given change type, the checklist items should be explicitly checked (or annotated N/A) so reviewers can confirm they were considered. Leaving them absent creates ambiguity.

Action required: Re-run the full suite per the template and update the checklist.


Coding Standards

Two inline comments have been posted on the diff for the following issues:

  1. Unintentional whitespace / line-ending changes — Five files (Invoke-LinkLanguageCheck.ps1, Markdown-Link-Check.ps1, Test-CopyrightHeaders.ps1, Invoke-LinkLanguageCheck.Tests.ps1, Test-CopyrightHeaders.Tests.ps1) show a line-1 diff that is visually identical in content. This is a CRLF/LF mismatch or trailing-whitespace artifact introduced during editing. These changes are out of scope and pollute the diff.

  2. Trailing-newline removal — Two files (Invoke-LinkLanguageCheck.ps1 and Validate-SkillStructure.Tests.ps1) have their final blank line silently removed. This was not declared in the PR scope and should be reverted unless there is a deliberate repo-wide convention to strip trailing newlines.


Code Quality

✅ No bugs, security issues, or logic errors found. The renames are mechanical, complete, and correct across all four production scripts and all five test files.


Action Items

  1. Revert the whitespace-only line-1 changes in the five affected files to eliminate CRLF/trailing-space noise.
  2. Restore the trailing blank lines in Invoke-LinkLanguageCheck.ps1 and Validate-SkillStructure.Tests.ps1.
  3. Complete the Required Automated Checks checklist in the PR description — run all eight commands and check (or mark N/A) each entry.

Generated by PR Review for issue #1314

@chaosdinosaur
Copy link
Copy Markdown
Collaborator Author

Addressing Review Feedback

All three action items from the automated review have been addressed in commit e06aabd:

1. ✅ Whitespace / line-ending changes — Fixed

Root cause identified as UTF-8 BOM stripping. All seven modified files had a EF BB BF BOM on main that was silently removed during editing. The BOM has been restored, which also resolves the six PSUseBOMForUnicodeEncodedFile failures in the PowerShell Lint CI check.

2. ✅ Trailing newline removal — Fixed

Trailing blank lines restored in Invoke-LinkLanguageCheck.ps1 and Validate-SkillStructure.Tests.ps1 to match the originals on main.

3. ℹ️ PR Template Compliance — Noted

The six missing automated check entries (spell-check, lint:frontmatter, validate:skills, lint:md-links, plugin:generate, docs:test) are all N/A for this change (script-only timestampTimestamp key renames). The PR description checklist should be updated to explicitly mark them as such.


Result: The combined diff against main now shows 11 insertions / 11 deletions — exclusively the intended timestampTimestamp key renames across 4 production scripts and 4 test files. No BOM artifacts, no whitespace noise, no trailing newline changes.

@chaosdinosaur
Copy link
Copy Markdown
Collaborator Author

Template Compliance Check Results

All template compliance checks pass on branch fix/1003-standardize-timestamp-key-casing as of commit e06aabdd.

✅ PSScriptAnalyzer Lint — PASS

All PowerShell files pass npm run lint:ps with zero violations, including the PSUseBOMForUnicodeEncodedFile rule.

✅ UTF-8 BOM Compliance — PASS

File BOM
scripts/linting/Invoke-LinkLanguageCheck.ps1 ✅ Present
scripts/linting/Markdown-Link-Check.ps1 ✅ Present
scripts/linting/Test-CopyrightHeaders.ps1 ✅ Present
scripts/linting/Validate-SkillStructure.ps1 ✅ Present
scripts/tests/linting/Invoke-LinkLanguageCheck.Tests.ps1 ✅ Present
scripts/tests/linting/Markdown-Link-Check.Tests.ps1 ➖ None (matches main)
scripts/tests/linting/Test-CopyrightHeaders.Tests.ps1 ✅ Present
scripts/tests/linting/Validate-SkillStructure.Tests.ps1 ✅ Present

✅ Timestamp Key Casing — PASS

All hashtable key assignments standardized from timestamp to Timestamp across 4 linting scripts and 4 test files. No remaining lowercase timestamp hashtable keys in scope.

✅ Pester Tests — PASS

Result:       Passed
Total:        653
Passed:       621
Failed:       0
Skipped:      0
Duration:     00:03:26

All linting tests pass with the updated Timestamp assertions.

@WilliamBerryiii
Copy link
Copy Markdown
Member

@chaosdinosaur ... we could also move this I guess to a CI Helper function ... thoughts?

@chaosdinosaur
Copy link
Copy Markdown
Collaborator Author

@WilliamBerryiii Good thought — here's a quick analysis:

Get-StandardTimestamp already lives in CIHelpers.psm1 (scripts/lib/Modules/CIHelpers.psm1 L553–L575). Every linting and security script already imports it. This PR's main contribution for SecurityClasses.psm1 is adding the missing Import-Module CIHelpers and replacing the inline .ToUniversalTime().ToString(...) with the shared Get-StandardTimestamp call — so the consolidation into a CI helper is effectively what's happening here.

If the suggestion is a higher-level helper (e.g., New-CIResultObject that auto-injects the Timestamp key), the case is weaker today because:

  • Timestamp is the only common field across all result hashtables — each script's shape is unique.
  • Timestamp = Get-StandardTimestamp is already a single-line, self-documenting call. A wrapper adds indirection without proportional benefit.
  • The root bug was key casing (timestamp vs Timestamp), which is better prevented by test assertions than by abstraction.

Recommendation: Keep as-is for this PR. If a second standard field emerges later (e.g., ScriptName, Platform), a result-builder helper in CIHelpers would start to pay off and should be tracked as a separate issue at that point.

@chaosdinosaur
Copy link
Copy Markdown
Collaborator Author

Update: @WilliamBerryiii raised a valid follow-up concern — the ISO 8601 timestamp validation regex (^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z$) is duplicated across 5 test files. If the format produced by Get-StandardTimestamp ever changes, all copies must be updated in lockstep.

This is better addressed by exporting a Get-StandardTimestampPattern function from CIHelpers so the regex lives alongside the formatter. Tracked as #1333 — separate from this PR's scope of key casing standardization.

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Advisory review — this PR is from a maintainer. Findings are informational only.

Review Summary

PR #1314 makes clean, focused, mechanical changes: renaming the timestamp hashtable key to Timestamp (PascalCase) in four linting scripts and their corresponding Pester test files. The implementation is correct and well-targeted. Two advisory observations are noted below.


Issue Alignment ✅

The PR clearly links Fixes #1003 and the changes directly address the issue’s stated goal of standardizing Timestamp casing across lint result JSON files. The scope is reasonable, and the intentional exclusion of three scripts using inline [datetime]::UtcNow is documented in Additional Notes.


PR Template Compliance ⚠️

Five required automated checks are unchecked in the checklist:

  • npm run spell-check
  • npm run lint:frontmatter
  • npm run validate:skills
  • npm run lint:md-links
  • npm run plugin:generate

The template labels these as required before merging. For a pure PowerShell script change, most are unlikely to surface regressions, but they should be run and checked off (or explicitly marked N/A) to satisfy the template requirement.


Coding Standards ✅

All changed files comply with the PowerShell conventions in .github/instructions/. Timestamp uses correct PascalCase, copyright headers are untouched, and the test assertions are updated consistently.


Code Quality — One Scope Observation 💡

scripts/tests/linting/FrontmatterValidation.Tests.ps1 lines 355–356 were not updated.

FrontmatterValidation.psm1 already uses Timestamp (PascalCase) in its ToHashtable() method (line 197 on main). The corresponding test still asserts the lowercase key:

$hash.ContainsKey('timestamp') | Should -BeTrue
$hash['timestamp'] | Should -Match '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z$'

The tests pass today because PowerShell @{} hashtables are case-insensitive, so .ContainsKey('timestamp') finds Timestamp. However, since the PR’s stated goal is to standardize casing across all lint result files, updating these assertions would complete the picture and accurately reflect the key name in serialized JSON output.

Suggested fix for scripts/tests/linting/FrontmatterValidation.Tests.ps1 lines 355–356:

# Before
$hash.ContainsKey('timestamp') | Should -BeTrue
$hash['timestamp'] | Should -Match '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z$'

# After
$hash.ContainsKey('Timestamp') | Should -BeTrue
$hash['Timestamp'] | Should -Match '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z$'

This file is not in the current diff; the fix can be included in this PR or as a follow-up commit.


Action Items

  1. Run the five unchecked automated checks and tick them off (or mark as N/A).
  2. Consider updating FrontmatterValidation.Tests.ps1 lines 355–356 to use 'Timestamp' for consistency with the PR’s standardization goal.

Generated by PR Review for issue #1314 · ● 8.2M

Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Advisory review, this PR is from a maintainer. Findings are informational only.

Review Summary

This PR makes a clean, well-scoped fix — renaming the timestamp hashtable key to Timestamp (PascalCase) in four linting scripts and their corresponding Pester test files. The implementation is correct, all eight files are consistently updated, and the tests accurately reflect the new casing. The intent aligns with the stated goal of completing the final batch of standardization work for issue #1003.

Two minor informational notes follow.


✅ Issue Alignment

The changes directly and completely address the stated goal of standardizing timestamp → Timestamp across the four remaining linting scripts and their test files, completing the series started in issues #994#1002.


⚠️ PR Template Compliance

The PR description omits several entries from the Required Automated Checks section of the template:

Check Status in PR
npm run lint:md ✅ checked
npm run lint:ps ✅ checked
npm run spell-check ❌ unchecked
npm run lint:frontmatter ❌ unchecked
npm run validate:skills ❌ unchecked
npm run lint:md-links ❌ unchecked
npm run plugin:generate ❌ unchecked
npm run docs:test ❌ not listed (present in template)

Several of these (frontmatter, skills, links, plugin, docs) are genuinely not applicable to pure .ps1 changes. However, the template lists all of them as "Required before merging," and leaving them unchecked without explanation makes it unclear whether they were run and passed or simply skipped. For future PRs in this series, consider checking non-applicable items with an (N/A — no .md/.yml/plugin changes) annotation, or confirming a full npm run lint:all pass, to keep the checklist unambiguous for reviewers.


💡 BOM Side Effect (Informational)

The initial fix commits accidentally stripped UTF-8 BOM bytes and trailing newlines from seven files; this was caught and corrected in commit e06aabd (fix(scripts): restore UTF-8 BOM and trailing newlines stripped during edits). The final file state is correct. No action required — just a note that configuring the editor (e.g., VS Code files.encoding: utf8bom, .editorconfig charset = utf-8-bom) to preserve BOM on save would prevent this class of noise commit in future edits to these files.


💡 Remaining Inconsistencies (Out of Scope — Noted)

As documented in the PR's Additional Notes, two security scripts still use ad-hoc datetime formatting instead of Get-StandardTimestamp:

  • scripts/security/Test-SHAStaleness.ps1 (line 493): Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"
  • scripts/security/Test-ActionVersionConsistency.ps1 (line 252): (Get-Date).ToString('yyyy-MM-ddTHH:mm:ss.fffZ')

The exclusion is intentional and clearly explained. Tracking follow-up issues for these two scripts would be a good next step to complete the full standardization.

Generated by PR Review for issue #1314 · ● 4.7M

@github-actions
Copy link
Copy Markdown
Contributor

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails
npm/basic-ftp 5.2.2 🟢 5.3
Details
CheckScoreReason
Code-Review⚠️ 0Found 1/30 approved changesets -- score normalized to 0
Packaging⚠️ -1packaging workflow not detected
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Maintained🟢 78 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 7
Binary-Artifacts🟢 10no binaries found in the repo
Security-Policy🟢 10security policy file detected
Token-Permissions🟢 9detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0

Scanned Files

  • package-lock.json

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.

Standardize Timestamp JSON key casing across all lint result files

4 participants