mirror of
https://github.com/microsoft/regorus.git
synced 2026-08-05 02:16:11 +00:00
Add comprehensive documentation and GitHub Copilot configuration: - docs/knowledge/: 17 deep-dive knowledge files covering value semantics, RVM architecture, builtins, FFI boundary, feature composition, error handling migration, policy evaluation security, Rego semantics, interpreter/compiler architecture, Azure Policy/RBAC, engine API, time builtins, language extension guide, tooling architecture, causality/partial eval, Rego compiler, Azure Policy aliases, and telemetry/diagnostics - .github/agents/: 16 role-specific AI agent definitions (red-teamer, semantics-expert, architect, performance-engineer, test-engineer, verification-engineer, security-auditor, reliability-engineer, support-engineer, ci-engineer, refactorer, api-steward, program-manager, demo-engineer, dx-engineer, tech-lead) - .github/skills/: 6 workflow skill definitions (thorough-review, design-alternatives, add-builtin, opa-conformance, security-review, verification) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: anakrish <35780660+anakrish@users.noreply.github.com>
156 lines
5.1 KiB
Markdown
156 lines
5.1 KiB
Markdown
<!-- Copyright (c) Microsoft Corporation. All rights reserved. -->
|
|
<!-- Licensed under the MIT License. -->
|
|
|
|
# Knowledge: Time Builtins Compatibility
|
|
|
|
Deep knowledge about the time builtin functions, especially the Go
|
|
`time.Parse` compatibility layer. Read this before modifying
|
|
`src/builtins/time/` or any time-related builtins.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
src/builtins/
|
|
time.rs Main time builtins (303 lines)
|
|
time/
|
|
compat.rs Go time.Parse compatibility layer (1,359 lines)
|
|
diff.rs Time difference calculation (83 lines)
|
|
```
|
|
|
|
`compat.rs` is the single most complex builtin module in the codebase.
|
|
|
|
## Why Go Compatibility Matters
|
|
|
|
OPA is written in Go and uses Go's `time.Parse()` function. Go's time parsing
|
|
is fundamentally different from standard approaches:
|
|
|
|
**Standard (C, Rust, Python)**: format strings with `%Y`, `%m`, `%d` etc.
|
|
|
|
**Go**: uses a **reference time** as the layout. The reference time is:
|
|
```
|
|
Mon Jan 2 15:04:05 MST 2006
|
|
```
|
|
This specific date/time was chosen because each component is unique:
|
|
- Month: January (1)
|
|
- Day: 2
|
|
- Hour: 15 (3 PM)
|
|
- Minute: 04
|
|
- Second: 05
|
|
- Year: 2006
|
|
- Timezone: MST
|
|
|
|
OPA test cases use Go layouts, so regorus must parse and format times using
|
|
this same convention to pass conformance tests.
|
|
|
|
## The compat.rs Module
|
|
|
|
This is essentially a **Rust port of Go's time parsing logic**. Key functions:
|
|
|
|
### `parse(layout, value)` → Parsed time
|
|
|
|
Implements Go's `time.Parse()`:
|
|
1. Scans the layout string for known reference time components
|
|
2. Extracts corresponding values from the input string
|
|
3. Handles timezone parsing, AM/PM, fractional seconds
|
|
4. Returns a Chrono `DateTime` or `NaiveDateTime`
|
|
|
|
### `format(time, layout)` → Formatted string
|
|
|
|
Implements Go's `time.Format()`:
|
|
1. Scans the layout string for reference time components
|
|
2. Substitutes actual time values
|
|
3. Handles timezone abbreviation, offset formatting
|
|
|
|
### `parse_duration(s)` → Duration
|
|
|
|
Parses Go-style duration strings: `"10h12m45s"`, `"1.5h"`, `"300ms"`.
|
|
Go's duration format is different from ISO 8601.
|
|
|
|
## Tricky Aspects
|
|
|
|
### Missing Components
|
|
|
|
Go's `time.Parse` allows missing year or time components. Chrono is stricter.
|
|
The compatibility layer fills in defaults:
|
|
- Missing year → 0 (or current year depending on context)
|
|
- Missing time → 00:00:00
|
|
- Missing timezone → UTC
|
|
|
|
### Timezone Parsing
|
|
|
|
Go has a custom timezone parsing approach that differs from standard timezone
|
|
databases. The compatibility layer handles:
|
|
- Named timezones (MST, EST, PST)
|
|
- Numeric offsets (+0700, -05:00)
|
|
- Legacy formats
|
|
- `parse_legacy_timezone()` for OPA-specific timezone handling
|
|
|
|
### Fractional Seconds
|
|
|
|
Go layouts use `.000` for milliseconds, `.000000` for microseconds,
|
|
`.000000000` for nanoseconds. The number of zeros determines precision.
|
|
The parser must count zeros to know the precision.
|
|
|
|
### Lint Suppressions
|
|
|
|
`compat.rs` suppresses several lints:
|
|
- `clippy::arithmetic_side_effects` — ported Go code uses arithmetic directly
|
|
- `clippy::unseparated_literal_suffix` — literal style from Go port
|
|
- `clippy::pattern_type_mismatch`
|
|
|
|
This is intentional — the module is a faithful port and the arithmetic has
|
|
been verified in the original Go implementation.
|
|
|
|
## Main Time Builtins (`time.rs`)
|
|
|
|
| Function | Purpose | Complexity |
|
|
|----------|---------|------------|
|
|
| `time.now_ns()` | Current time in nanoseconds | Low |
|
|
| `time.parse_rfc3339_ns()` | Parse RFC 3339 timestamp | Low |
|
|
| `time.parse_ns()` | Parse with Go layout → nanoseconds | High (uses compat.rs) |
|
|
| `time.parse_duration_ns()` | Parse Go duration string | Medium |
|
|
| `time.format()` | Format with Go layout | High (uses compat.rs) |
|
|
| `time.date()` | Extract year/month/day | Medium |
|
|
| `time.clock()` | Extract hour/minute/second | Medium |
|
|
| `time.weekday()` | Day of week string | Low |
|
|
| `time.add_date()` | Date arithmetic | Medium |
|
|
| `time.diff()` | Time difference | Medium |
|
|
|
|
### Date Arithmetic
|
|
|
|
`time.add_date()` uses checked arithmetic:
|
|
- `checked_add()` and `checked_sub_months()` for year/month bounds
|
|
- Leap year adjustments
|
|
- Returns `Undefined` on overflow (OPA compatibility)
|
|
|
|
### Nanosecond Precision
|
|
|
|
All time functions work with nanosecond timestamps internally.
|
|
`safe_timestamp_nanos()` prevents overflow when converting from seconds
|
|
to nanoseconds.
|
|
|
|
### Predefined Format Layouts
|
|
|
|
`layout_with_predefined_formats()` maps OPA layout names to Chrono formats:
|
|
- RFC 3339, RFC 822, RFC 850
|
|
- ANSIC, Unix, Kitchen, Stamp formats
|
|
- These must match OPA's predefined layouts exactly
|
|
|
|
## OPA Conformance
|
|
|
|
Time builtins are a rich source of conformance edge cases:
|
|
|
|
1. **Go layout parsing** must match Go's behavior exactly
|
|
2. **Nanosecond overflow** must return `Undefined`, not error
|
|
3. **Timezone names** must be recognized consistently
|
|
4. **Duration parsing** must handle Go's format (not ISO 8601)
|
|
5. **Date arithmetic** edge cases (Feb 29, month overflow)
|
|
|
|
## Dependencies
|
|
|
|
- `chrono` — date/time handling (feature-gated behind `time`)
|
|
- `chrono-tz` — timezone database (feature-gated behind `time`)
|
|
|
|
Both are optional dependencies. Time builtins are not available in `no_std`
|
|
or `opa-no-std` configurations.
|