Recertification Markers
Relevant source files
The following files were used as context for generating this wiki page:- iac-recert-engine/internal/scan/recert_checker.go
- iac-recert-engine/internal/engine/engine.go
- iac-recert-engine/example.config.yaml
- iac-recert-engine/internal/config/types.go
- iac-recert-engine/internal/types/types.go
- iac-recert-engine/internal/scan/recert_checker_test.go
- iac-recert-engine/internal/provider/github.go
Recertification Markers, referred to as "decorators" in the configuration, are strings of text automatically added to the beginning of a file when a recertification pull request is created. Their primary purpose is to modify the file's content, which in turn creates a new commit in the Git history. This updates the file's last modification date.
The engine relies on the last modification date of a file to determine if it has passed its recertification deadline. By programmatically updating the file with a marker, the recertification "clock" for that file is effectively reset upon merging the PR. This mechanism forms the core feedback loop of the entire recertification process.
Configuration
Recertification markers are configured within each file pattern definition in the main config.yaml file.
Sources: example.config.yaml:30-31, internal/config/types.go:42-49
The decorator Property
The decorator is an optional string property within a pattern block. If defined, this string will be used as the marker.
| Property | Type | Description |
|---|---|---|
decorator | string | The text to add to the top of a file upon recertification. It supports a {timestamp} placeholder which is replaced with the current time in RFC3339 format. |
Sources: internal/config/types.go:48, internal/engine/engine.go:211
Example Configuration
Here is an example from example.config.yaml showing different decorators for different file types. Note the use of language-specific comment characters.
patterns:
- name: "terraform-prod"
# ...
recertification_days: 180
# Decorator for Terraform files
decorator: "# Last Recertification: {timestamp}\n"
- name: "k8s-manifests"
# ...
recertification_days: 90
# Decorator for YAML files
decorator: "# Last Recertification: {timestamp}\n"
- name: "iac-recert-engine"
# ...
recertification_days: 1
# Decorator for Go files
decorator: "// Last Recertification: {timestamp}\n"
Sources: example.config.yaml:30-49
Recertification Check Logic
The engine determines if a file needs recertification by comparing the time elapsed since its last modification against a configured threshold. The last modification date is retrieved from the Git history for each file.
Sources: internal/scan/recert_checker.go:79-81, internal/scan/git_history.go:34-37
The following diagram illustrates the checking process for a single file.
This diagram shows the decision flow within the Checker.Check function.
Sources: internal/scan/recert_checker.go:23-118
Priority Calculation
A priority level is assigned to each file based on how long it has been since its last modification relative to its recertification threshold. This helps prioritize which files need attention most urgently.
The priority is calculated using the ratio: days_since / threshold_days.
| Priority | Condition (ratio = days_since / threshold_days) | Status |
|---|---|---|
Critical | ratio > 1.5 | Overdue |
High | ratio >= 1.0 | Overdue |
Medium | ratio >= 0.8 | Approaching |
Low | ratio < 0.8 | OK |
Sources: internal/scan/recert_checker.go:84-97, internal/scan/recert_checker_test.go:39-43
Marker Application Process
When the engine processes a group of files that require recertification, it generates the necessary file changes, including adding the decorator, before creating a commit and pull request.
The process ensures that old markers are removed before new ones are added, preventing an accumulation of markers in the file.
Sources: internal/engine/engine.go:183-215
Application Flow
The following sequence diagram details the steps taken by the Engine to apply a decorator to a file.
This diagram shows the decorator application logic within the processGroup function.
Sources: internal/engine/engine.go:183-222, internal/provider/github.go:160-213
Implementation Details
The engine uses a regular expression to find and remove a potentially existing decorator. This prevents duplicate markers on subsequent recertifications.
// internal/engine/engine.go:208-209
// Remove existing decorator
existingDecorator := regexp.MustCompile(`^` + regexp.QuoteMeta(pattern.Decorator) + `.*\n?`)
content = existingDecorator.ReplaceAllString(content, "")
Sources: internal/engine/engine.go:208-209
After removing the old marker, the new one with an updated timestamp is prepended to the file's content.
// internal/engine/engine.go:211-212
// Apply new decorator
decorator := strings.ReplaceAll(pattern.Decorator, "{timestamp}", time.Now().Format(time.RFC3339))
content = decorator + content
Sources: internal/engine/engine.go:211-212
Relevant Data Structures
The marker system is supported by fields in the main configuration and runtime data structures.
Pattern Configuration
This struct defines a file pattern and its associated recertification rules, including the decorator.
| Field | Type | Description |
|---|---|---|
Name | string | A unique name for the pattern. |
Paths | []string | Glob patterns for files to include. |
Exclude | []string | Glob patterns for files to exclude. |
RecertificationDays | int | The number of days before a file needs recertification. |
Decorator | string | The marker string to apply to the file. |
Sources: internal/config/types.go:42-49
RecertCheckResult
This struct holds the outcome of a recertification check for a single file.
| Field | Type | Description |
|---|---|---|
File | FileInfo | Information about the scanned file. |
PatternName | string | The name of the pattern that the file matched. |
DaysSince | int | Number of days since the file was last modified. |
Threshold | int | The recertification period in days from the pattern. |
Priority | string | The calculated priority (Critical, High, Medium, Low). |
NeedsRecert | bool | True if DaysSince is greater than or equal to Threshold. |
NextDueDate | time.Time | The calculated date when the file will next be due for recertification. |
Sources: internal/types/types.go:12-21