Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions docs/ARCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ This is not dogma: for UI/frontend, bot/automation tasks, glue code, ML/data/AI-

### 5.2 Code Traceability (`@hlv` markers)

Every error code, invariant, and constraint rule from contracts MUST have an `@hlv <ID>` marker next to the test that verifies it:
Every error code, invariant, and constraint rule from contracts MUST have an `@hlv <ID>` marker next to the test that verifies it. Constraint rules that have `check_command` are exempt — they are verified programmatically:

```rust
// @ctx: stock validation for order.create contract
Expand All @@ -333,7 +333,7 @@ fn test_no_sql_injection() { ... }

`@ctx` comments are navigation hints for the LLM. They help understand context quickly without reading the entire file. They are optional, but recommended for complex logic.

`hlv check` automatically collects all IDs from `contracts/*.yaml` (`errors[].code`, `invariants[].id`) and `constraints/*.yaml` (`rules[].id`), then scans `src/` and `tests/` for markers. Missing markers produce warning `CTR-010`; in phase `implemented` and later they block `/validate`.
`hlv check` automatically collects all IDs from `contracts/*.yaml` (`errors[].code`, `invariants[].id`) and `constraints/*.yaml` (`rules[].id`), then scans `src/` and `tests/` for markers. Rules with `check_command` are skipped (verified by their command via CST-050). Missing markers produce warning `CTR-010`; in phase `implemented` and later they block `/validate`.

### 5.3 Agent Protocol

Expand Down Expand Up @@ -478,9 +478,11 @@ Architecture for managing constraint files in `human/constraints/`.

**CRUD.** `hlv constraints add` creates a new YAML file from a `ConstraintFile` template. `add-rule` / `remove-rule` mutate the `rules[]` array inside an existing file. All operations follow: read file -> deserialize -> mutate -> serialize -> write.

**`hlv check` checks.** `CST-010` - file from `project.yaml -> constraints` not found. `CST-020` - duplicate `rule.id` values inside the file. `CST-030` - invalid severity. `CST-010`/`020` are errors (block `/verify`), `CST-030` is a warning.
**`hlv check` checks.** `CST-010` - file from `project.yaml -> constraints` not found. `CST-020` - duplicate `rule.id` values inside the file. `CST-030` - invalid `severity` or `error_level` value. `CST-050` - runs `check_command` for each constraint rule that has one; severity is determined by the rule's `error_level` override, or mapped from rule severity (`critical`/`high` -> error, `medium`/`low` -> warning). `CST-060` - runs file-level `check_command` on the constraint file itself; failure is always an error. `CST-010`/`020` are errors (block `/verify`), `CST-030` is a warning.

**Contract linkage.** Contracts refer to constraint rules through `depends_on_constraints`. `hlv check` (`CTR-010`) verifies that every `rule.id` from constraints has an `@hlv` marker in code.
**`hlv constraints check`.** Runs `check_command` for constraint rules with additional filters: `hlv constraints check <constraint>`, `--rule <id>`, `--json`. The same checks also run as part of `hlv check`.

**Contract linkage.** Contracts refer to constraint rules through `depends_on_constraints`. `hlv check` (`CTR-010`) verifies that every `rule.id` from constraints has an `@hlv` marker in code. Rules that have `check_command` are exempt from the `@hlv` marker requirement — they are verified programmatically by their command.

---

Expand Down
19 changes: 15 additions & 4 deletions docs/SPECS.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,9 @@ CRUD management for constraint files in `human/constraints/`. Each file is a rul
| `hlv constraints show <name> [--json]` | Show the content of a constraint file (all rules, owner, intent) |
| `hlv constraints add <name> [--owner <owner>] [--intent <text>] [--applies-to <scope>]` | Create a new constraint file |
| `hlv constraints remove <name> [--force]` | Remove a constraint file. Without `--force`, confirmation is required |
| `hlv constraints add-rule <constraint> <rule-id> --severity <sev> --statement <text>` | Add a rule to an existing constraint file |
| `hlv constraints add-rule <constraint> <rule-id> --severity <sev> --statement <text> [--check-command <cmd>] [--check-cwd <dir>] [--error-level <lvl>]` | Add a rule to an existing constraint file. Optional: `--check-command` sets a shell command to verify the rule, `--check-cwd` sets the working directory, `--error-level` overrides diagnostic severity (`error`, `warning`, `info`) |
| `hlv constraints remove-rule <constraint> <rule-id>` | Remove a rule from a constraint file |
| `hlv constraints check [<constraint>] [--rule <id>] [--json]` | Run `check_command` for constraint rules. Optionally filter by constraint name or rule ID |

`<name>` is the file name without extension (for example `security` -> `human/constraints/security.yaml`). Severity values are `critical`, `high`, `medium`, `low`.

Expand Down Expand Up @@ -531,6 +532,9 @@ rules:
statement: "Secrets must not appear in logs"
enforcement:
- log_policy_check
check_command: "grep -rn 'secret\\|password' src/ && exit 1 || exit 0"
check_cwd: "llm"
error_level: error
exceptions:
process: "Requires security team approval"
max_duration_days: 30
Expand All @@ -547,6 +551,9 @@ exceptions:
| `rules[].severity` | enum | Severity: `critical`, `high`, `medium`, `low` |
| `rules[].statement` | string | Rule wording |
| `rules[].enforcement[]` | array | Verification methods (`sast`, `integration_test`, `runtime_scan`, etc.) |
| `rules[].check_command` | string (optional) | Shell command to verify the rule (used by `CST-050` and `hlv constraints check`) |
| `rules[].check_cwd` | string (optional) | Working directory for `check_command` (relative to project root; defaults to project root) |
| `rules[].error_level` | enum (optional) | Override diagnostic severity: `error`, `warning`, `info`. If unset, mapped from `severity` (`critical`/`high` -> error, `medium`/`low` -> warning) |
| `exceptions` | object | Exception process (`process`, `max_duration_days`) |

Rust model: `model::policy::ConstraintFile`. Schema: `schema/constraint-schema.json`.
Expand All @@ -561,7 +568,9 @@ Integrity checks for constraint files, executed by `hlv check`.
|-----|---------|--------------|
| `CST-010` | error | Constraint file referenced in `project.yaml -> constraints` is not found on disk |
| `CST-020` | error | Duplicate `rule.id` values within the same constraint file |
| `CST-030` | error | Invalid `severity` value (allowed: `critical`, `high`, `medium`, `low`) |
| `CST-030` | error | Invalid `severity` value (allowed: `critical`, `high`, `medium`, `low`) or invalid `error_level` (allowed: `error`, `warning`, `info`) |
| `CST-050` | varies | Runs `check_command` for a constraint rule. Severity is determined by `error_level` override, or mapped from rule severity (`critical`/`high` -> error, `medium`/`low` -> warning) |
| `CST-060` | error | Runs file-level `check_command` on the constraint file. Failure is always an error |

These checks run automatically as part of `hlv check` and block `/verify` when reported as errors.

Expand Down Expand Up @@ -597,7 +606,7 @@ Important notes:
| `CTR-002` | error | Missing contract ID in Markdown header |
| `CTR-003` | error | Missing contract version in Markdown header |
| `CTR-004` | error | Markdown contract version differs from `project.yaml` |
| `CTR-010` | error / warning | Missing required contract section (error) or missing `@hlv` marker in code trace (warning) |
| `CTR-010` | error / warning | Missing required contract section (error) or missing `@hlv` marker in code trace (warning). Constraint rules with `check_command` are exempt from the marker requirement |
| `CTR-020` | warning | Contract source link points to missing file |
| `CTR-030` | error | Invalid Input YAML block in contract Markdown |
| `CTR-031` | error | Missing Input YAML block in contract Markdown |
Expand Down Expand Up @@ -670,7 +679,9 @@ Important notes:
|-----|---------|--------------|
| `CST-010` | error | Constraint file is missing or unparsable |
| `CST-020` | error | Duplicate `rules[].id` in one constraint file |
| `CST-030` | error | Invalid `rules[].severity` |
| `CST-030` | error | Invalid `rules[].severity` or `rules[].error_level` |
| `CST-050` | varies | Rule-level `check_command` failed (severity from `error_level` or mapped from rule severity) |
| `CST-060` | error | File-level `check_command` failed |

#### LLM Map (`MAP-*`)

Expand Down
10 changes: 8 additions & 2 deletions docs/WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ Agents work in parallel inside a group. Between groups - git commit.

**`llm/map.yaml` is the main navigator.** When creating a new file, the agent MUST add an entry to `llm/map.yaml` with a description sufficient to choose the file without opening it. The LLM finds code by descriptions in `map.yaml`, not by file names. `hlv check` verifies that all entries exist on disk.

**`@hlv` markers.** Every test must carry an `@hlv <ID>` marker pointing to an error code, invariant, or constraint rule from contracts. This provides 100% contract->code traceability. `hlv check` verifies that all IDs are covered. Example:
**`@hlv` markers.** Every test must carry an `@hlv <ID>` marker pointing to an error code, invariant, or constraint rule from contracts. This provides 100% contract->code traceability. `hlv check` verifies that all IDs are covered. Constraint rules that have `check_command` are exempt — they are verified by their command, not by markers. Example:

```rust
// @ctx: validates stock availability check from order.create contract
Expand Down Expand Up @@ -543,7 +543,7 @@ hlv milestone abort # abort milestone
/generate # artifacts -> contracts + validation + stages

# Verification
hlv check # structural validation + run gate commands
hlv check # structural validation + run gate commands + constraint checks (CST-050)
hlv check --watch # same + watch
/verify # full verification (structure + semantics)

Expand Down Expand Up @@ -581,6 +581,12 @@ hlv stage meta <N> set|delete <key> [<value>]
hlv milestone label add|remove <label>
hlv milestone meta set|delete <key> [<value>]

# Constraint checks
hlv constraints check # run check_command for all rules
hlv constraints check observability # filter by constraint
hlv constraints check --rule my_rule # filter by rule
hlv constraints check --json # JSON output

# Artifacts and glossary
hlv artifacts [--global|--milestone] [--json]
hlv artifacts show <name> [--json]
Expand Down
21 changes: 21 additions & 0 deletions schema/constraint-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
"type": "string",
"description": "Purpose description"
},
"check_command": {
"type": "string",
"description": "Shell command to check this entire constraint file (executed via sh -c)"
},
"check_cwd": {
"type": "string",
"description": "Working directory for check_command, relative to project root"
},
"rules": {
"type": "array",
"items": { "$ref": "#/$defs/ConstraintRule" }
Expand Down Expand Up @@ -54,6 +62,19 @@
"items": { "type": "string" },
"default": [],
"description": "Enforcement mechanisms"
},
"check_command": {
"type": "string",
"description": "Shell command to check this rule (executed via sh -c)"
},
"check_cwd": {
"type": "string",
"description": "Working directory for check_command, relative to project root"
},
"error_level": {
"type": "string",
"enum": ["error", "warning", "info"],
"description": "Override diagnostic level for check failures. If omitted, derived from severity (critical|high → error, medium|low → warning)"
}
},
"additionalProperties": false
Expand Down
21 changes: 21 additions & 0 deletions schema/security-constraints-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
"intent": {
"type": "string"
},
"check_command": {
"type": "string",
"description": "Shell command to check this entire constraint file (executed via sh -c)"
},
"check_cwd": {
"type": "string",
"description": "Working directory for check_command, relative to project root"
},
"rules": {
"type": "array",
"items": { "$ref": "#/$defs/SecurityConstraintRule" },
Expand Down Expand Up @@ -56,6 +64,19 @@
},
"description": "How this rule is verified",
"default": []
},
"check_command": {
"type": "string",
"description": "Shell command to check this rule (executed via sh -c)"
},
"check_cwd": {
"type": "string",
"description": "Working directory for check_command, relative to project root"
},
"error_level": {
"type": "string",
"enum": ["error", "warning", "info"],
"description": "Override diagnostic level for check failures. If omitted, derived from severity (critical|high → error, medium|low → warning)"
}
},
"additionalProperties": false
Expand Down
4 changes: 2 additions & 2 deletions skills/implement/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,8 @@ it('masks PII in logs', () => { ... });
1. One `@hlv` marker per validation/constraint per test. A test may carry multiple markers if it covers several validations.
2. Every `errors[].code` from every contract YAML must appear as `@hlv <code>` somewhere in `src/` or `tests/`.
3. Every `invariants[].id` must appear as `@hlv <id>`.
4. Every constraint `rules[].id` must appear as `@hlv <id>`.
5. `hlv check` reports missing markers as warnings (`CTR-010`). At `implemented` phase and later, these become hard warnings that block `/validate`.
4. Every constraint `rules[].id` must appear as `@hlv <id>` — except rules that have `check_command` (they are verified programmatically, not via markers).
5. `hlv check` reports missing markers as warnings (`CTR-010`). At `implemented` phase and later, these become hard warnings that block `/validate`. `hlv check` also runs `check_command` for rules that define one (CST-050/CST-060).

### Verification

Expand Down
4 changes: 3 additions & 1 deletion skills/validate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ gate_results:

### Step 3b: Constraint rule coverage

Check that every rule in rule-based constraint files (`human/constraints/*.yaml`) has a corresponding `@hlv <rule-id>` marker in `llm/src/` or `tests/`. Run `hlv check` and review CTR-010 diagnostics for missing constraint markers.
Check that every rule in rule-based constraint files (`human/constraints/*.yaml`) has a corresponding `@hlv <rule-id>` marker in `llm/src/` or `tests/`. Rules with `check_command` are exempt — they are verified programmatically. Run `hlv check` and review CTR-010 diagnostics for missing constraint markers.

`hlv check` also executes `check_command` for rules that define one (CST-050/CST-060). Review diagnostics: rules with `error_level: error` (or `critical`/`high` severity without an override) block release. Add failing checks to the remediation plan (Step 4a).

For each critical rule without coverage, add it to the remediation plan (Step 4a).

Expand Down
4 changes: 4 additions & 0 deletions src/check/code_trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ pub fn check_code_trace(
if let Some(rules) = value.get("rules").and_then(|r| r.as_sequence()) {
for rule in rules {
if let Some(id) = rule.get("id").and_then(|i| i.as_str()) {
// Rules with check_command are verified programmatically, not via @hlv markers
if rule.get("check_command").is_some() {
continue;
}
expected.push(ExpectedMarker {
id: id.to_string(),
kind: "constraint",
Expand Down
Loading
Loading