Constraint Management
Intro
A Constraint is an explicit rule or limit the project must respect: budget
ceilings, latency SLOs, team capacity, compliance requirements, dependency
restrictions. Capturing constraints as first-class entities makes them
referenceable from decisions and visible to trade-off analysis.
Overview
Shape
---
apiVersion: processkit.projectious.work/v2
kind: Constraint
metadata:
id: CONST-p99-latency
created: 2026-04-06T00:00:00Z
spec:
name: p99-latency
description: "API p99 latency must stay under 200ms under normal load."
kind: slo # budget | slo | regulatory | capacity | dependency | policy | other
severity: hard # hard | soft | advisory
measurement: "p99 of request duration over 5-minute windows"
target: "< 200ms"
source: "Customer SLA, signed 2026-01-15"
active: true
---
Workflow
- Pick
CONST-<short-name>.
- Set
kind — budget, SLO, regulatory, capacity, dependency, policy, or other.
- Set
severity: hard (cannot be violated), soft (flagged but overridable),
advisory (informational).
- Describe the
measurement (how you know if it's met) and the target.
- Record the
source — where the constraint came from (contract, regulation,
owner decision).
Using constraints
- DecisionRecords link via
spec.related_constraints when a decision was
shaped by a constraint.
- WorkItems add
labels.constraint when the work exists because of a constraint.
- Scope-specific constraints use Bindings such as
constraint-scope.
Cost-policy Artifacts apply through Binding(type=budget-application)
to the WorkItem or Scope they govern.
Gotchas
Agent-specific failure modes — provider-neutral pause-and-self-check items:
- Constraint without a measurable threshold. "Performance must
be good" is not a Constraint; "p99 latency must be under 200ms
on the checkout endpoint" is. Without a threshold, you can't
know whether the Constraint is satisfied.
- Treating Constraints as suggestions. Constraints are
requirements. Decisions and WorkItems should explicitly reference
the relevant CONSTRAINT-ID and confirm compliance, not hand-wave.
If a Constraint is only sometimes true, it's a guideline, not a
Constraint.
- Forgetting the source / owner of the Constraint. Where did
this Constraint come from — legal, finance, oncall, the user's
preference? The source matters because lifting it requires going
back to the source. Always set
source / owner fields.
- Creating Constraints that contradict each other. Two
Constraints saying "ship as fast as possible" and "no production
changes after 5pm" can both be valid, but the conflict must be
noted explicitly so decisions can choose between them. Silent
conflicts produce inconsistent behavior.
- Hand-waving "complies with X" without referencing the
CONSTRAINT-ID. When a workitem or decision satisfies a
Constraint, link the CONSTRAINT-ID explicitly. "We follow GDPR"
with no link is unverifiable.
- Confusing Constraints with Decisions. A Constraint is a
fixed rule the project respects ("budget ≤ $50k"); a Decision is
a choice someone made ("we picked Postgres over MySQL"). If
someone could change it tomorrow without external pressure, it's
a Decision.
- Constraints without expiry or review cadence. Some
Constraints are temporary ("hiring freeze through Q3"). Set a
review date so the Constraint doesn't become permanent by
default.
Full reference
Fields
| Field |
Type |
Notes |
name |
string |
kebab-case identifier |
description |
string |
One sentence |
kind |
enum |
budget / slo / regulatory / capacity / dependency / policy / other |
severity |
enum |
hard / soft / advisory |
measurement |
string |
How the constraint is measured |
target |
string |
The threshold or boundary |
source |
string |
Where the constraint comes from |
active |
bool |
false = no longer in effect |
violations |
list |
Log-style list of known violations (optional, prefer LogEntries) |
Constraint violations
When a hard constraint is violated, write a constraint.violated LogEntry
rather than editing the Constraint file. Repeated violations may motivate a
DecisionRecord to relax the constraint or address the underlying cause.
Retiring a constraint
Set active: false and log constraint.retired. Do not delete — historical
decisions may reference the constraint as part of their rationale.
1---2name: constraint-management3description: Manage Constraint entities — rules and limits the project must respect (budget, latency SLO, team size, compliance). Use when recording a rule, limit, or boundary that affects decisions — budget ceiling, latency SLO, regulatory requirement, team bandwidth.4---56# Constraint Management78## Intro910A Constraint is an explicit rule or limit the project must respect: budget11ceilings, latency SLOs, team capacity, compliance requirements, dependency12restrictions. Capturing constraints as first-class entities makes them13referenceable from decisions and visible to trade-off analysis.1415## Overview1617### Shape1819```yaml20---21apiVersion: processkit.projectious.work/v222kind: Constraint23metadata:24 id: CONST-p99-latency25 created: 2026-04-06T00:00:00Z26spec:27 name: p99-latency28 description: "API p99 latency must stay under 200ms under normal load."29 kind: slo # budget | slo | regulatory | capacity | dependency | policy | other30 severity: hard # hard | soft | advisory31 measurement: "p99 of request duration over 5-minute windows"32 target: "< 200ms"33 source: "Customer SLA, signed 2026-01-15"34 active: true35---36```3738### Workflow39401. Pick `CONST-<short-name>`.412. Set `kind` — budget, SLO, regulatory, capacity, dependency, policy, or other.423. Set `severity`: `hard` (cannot be violated), `soft` (flagged but overridable),43 `advisory` (informational).444. Describe the `measurement` (how you know if it's met) and the `target`.455. Record the `source` — where the constraint came from (contract, regulation,46 owner decision).4748### Using constraints4950- DecisionRecords link via `spec.related_constraints` when a decision was51 shaped by a constraint.52- WorkItems add `labels.constraint` when the work exists because of a constraint.53- Scope-specific constraints use Bindings such as `constraint-scope`.54 Cost-policy Artifacts apply through `Binding(type=budget-application)`55 to the WorkItem or Scope they govern.5657## Gotchas5859Agent-specific failure modes — provider-neutral pause-and-self-check items:6061- **Constraint without a measurable threshold.** "Performance must62 be good" is not a Constraint; "p99 latency must be under 200ms63 on the checkout endpoint" is. Without a threshold, you can't64 know whether the Constraint is satisfied.65- **Treating Constraints as suggestions.** Constraints are66 requirements. Decisions and WorkItems should explicitly reference67 the relevant CONSTRAINT-ID and confirm compliance, not hand-wave.68 If a Constraint is only sometimes true, it's a guideline, not a69 Constraint.70- **Forgetting the source / owner of the Constraint.** Where did71 this Constraint come from — legal, finance, oncall, the user's72 preference? The source matters because lifting it requires going73 back to the source. Always set `source` / `owner` fields.74- **Creating Constraints that contradict each other.** Two75 Constraints saying "ship as fast as possible" and "no production76 changes after 5pm" can both be valid, but the conflict must be77 noted explicitly so decisions can choose between them. Silent78 conflicts produce inconsistent behavior.79- **Hand-waving "complies with X" without referencing the80 CONSTRAINT-ID.** When a workitem or decision satisfies a81 Constraint, link the CONSTRAINT-ID explicitly. "We follow GDPR"82 with no link is unverifiable.83- **Confusing Constraints with Decisions.** A Constraint is a84 fixed rule the project respects ("budget ≤ $50k"); a Decision is85 a choice someone made ("we picked Postgres over MySQL"). If86 someone could change it tomorrow without external pressure, it's87 a Decision.88- **Constraints without expiry or review cadence.** Some89 Constraints are temporary ("hiring freeze through Q3"). Set a90 review date so the Constraint doesn't become permanent by91 default.9293## Full reference9495### Fields9697| Field | Type | Notes |98|---------------|-------------|-----------------------------------------------------------|99| `name` | string | kebab-case identifier |100| `description` | string | One sentence |101| `kind` | enum | `budget` / `slo` / `regulatory` / `capacity` / `dependency` / `policy` / `other` |102| `severity` | enum | `hard` / `soft` / `advisory` |103| `measurement` | string | How the constraint is measured |104| `target` | string | The threshold or boundary |105| `source` | string | Where the constraint comes from |106| `active` | bool | `false` = no longer in effect |107| `violations` | list | Log-style list of known violations (optional, prefer LogEntries) |108109### Constraint violations110111When a hard constraint is violated, write a `constraint.violated` LogEntry112rather than editing the Constraint file. Repeated violations may motivate a113DecisionRecord to relax the constraint or address the underlying cause.114115### Retiring a constraint116117Set `active: false` and log `constraint.retired`. Do not delete — historical118decisions may reference the constraint as part of their rationale.