Skip to content

Commit de946a2

Browse files
committed
fix: preserve owner-controlled production boundary (#5)
1 parent bbaf3d5 commit de946a2

13 files changed

Lines changed: 61 additions & 28 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ engineering-process metrics --obligations .engineering/effective-obligations.jso
6363
## Policy model
6464

6565
- **Locked** controls cannot be changed locally (fresh-context independent review, fail-closed Protected routing, exact-revision evidence, secrets, traceability, human production boundary).
66+
- The human production boundary requires manual human authorization and promotion. A repository owner may satisfy it; it does not implicitly require a second human. Automation and agents may not authorize or promote production.
6667
- **Extensible** controls can only be strengthened.
6768
- **Overridable** mechanics belong to repositories (commands, paths, runtime, framework, environments).
6869
- Profiles describe engineering/risk domains (`generic`, `frontend`, `backend`), never languages or frameworks.

docs/adoption.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
Repository-local technology is deliberately opaque to policy. Put commands under `overrides.validation.commands`; add sensitive paths/characteristics and domain triggers when they strengthen classification. Never copy the canonical policy into the manifest.
1111

12+
## Production authority and independent review
13+
14+
The human production boundary and independent review are separate controls. Every change still requires fresh-context, implementation-independent review evidence. Production authorization and promotion remain manual human actions, and automation or agents may not perform them. For an owner-controlled repository, the owner's explicit authorization and manual merge or promotion satisfy the human boundary; a second human GitHub reviewer is not implicitly required. Repositories with multiple authorized maintainers may configure a stronger branch or Environment reviewer gate.
15+
1216
## Mature repository migration
1317

1418
Initialization is non-destructive. If `AGENTS.md`, `CLAUDE.md`, or the process validation workflow is repository-owned, normal `init` stops before creating `.engineering/process.yaml`. Do not use `--force` to bypass this boundary.

docs/design/common-software-engineering-process-design-v4.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,8 @@ Where approval is required, it should be recorded in durable project evidence.
654654

655655
Production deployment and production-authority changes remain human controlled unless a future explicit policy changes that boundary.
656656

657+
This boundary prohibits an implementation agent or automation from authorizing or promoting production. It does not by itself require two different human identities. In an owner-controlled repository, explicit owner authorization followed by manual owner merge or promotion satisfies the boundary. Fresh-context independent review remains a separate mandatory control and must not be issued by the implementation context. Repositories with multiple authorized maintainers may strengthen native enforcement with a distinct GitHub reviewer.
658+
657659
---
658660

659661
## 7.7 Scope discipline
@@ -1929,14 +1931,14 @@ Recommended enforcement mapping:
19291931
|---|---|
19301932
| Required CI/test verdict | GitHub required status check |
19311933
| Protected branch/merge rule | GitHub ruleset / protected branch |
1932-
| Human production approval | GitHub Environment required reviewer where available |
1933-
| Prevent deployment self-approval | GitHub Environment self-review prevention |
1934+
| Human production authorization | Manual owner/authorized-maintainer merge or promotion; optionally a GitHub Environment required reviewer |
1935+
| Prevent autonomous deployment | Repository permissions and workflow design that deny agents/automation production authority |
19341936
| Process/manifest legality | engineering-process validator |
19351937
| Protected classification | classification policy + deterministic CI signals |
19361938
| Exact revision evidence | attestation/evidence join |
19371939
| Specialist procedure | Agent Skill / human procedure |
19381940

1939-
GitHub documents required status checks that block merge until required checks pass, and protected environments can require reviewers and prevent the deployment initiator from approving their own deployment.[^R12][^R13]
1941+
GitHub documents required status checks that block merge until required checks pass, and protected environments can require reviewers and prevent the deployment initiator from approving their own deployment.[^R12][^R13] The latter is an optional stronger multi-human control, not an unconditional interpretation of the canonical human production boundary.
19401942

19411943
The canonical process owns the rule's semantics; native platforms enforce it when they have a reliable mechanism.
19421944

enforcement/github/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ The process reports policy meaning; configure GitHub for the stronger enforcemen
55
| Obligation | GitHub mechanism |
66
|---|---|
77
| CI/process readiness before merge | Ruleset required status checks (`engineering-process`, tests) |
8-
| Review and protected branch | Branch ruleset; require pull request and approvals |
9-
| Production human approval | Protected Environment required reviewer |
10-
| No deployment self-approval | Environment “prevent self-review” |
8+
| Review and protected branch | Branch ruleset; require pull request and status checks; require human approvals when repository governance calls for them |
9+
| Production human authorization | Manual owner/authorized-maintainer merge or promotion; optionally a protected Environment required reviewer |
10+
| No autonomous production | Do not grant agents or automation production approval or merge authority |
1111
| Minimal token bootstrap | Generated assistant files, not branch prose |
1212

13-
The reusable workflow in `reusable-workflows/process-readiness.yml` validates the repository and joins evidence. Repository administrators must configure rulesets and Environments because permissions/plans differ; prompt instructions are not a substitute.
14-
13+
The reusable workflow in `reusable-workflows/process-readiness.yml` validates the repository and joins evidence. Repository administrators must configure rulesets and Environments because permissions, plans, and collaborator topology differ; prompt instructions are not a substitute. A required Environment reviewer plus self-review prevention is a valid stronger control when a distinct authorized human exists. It is not the canonical meaning of the human production boundary and is not mandatory for an owner-controlled repository.

policy/core.yaml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
schema_version: 1
22
process:
3-
version: 1.0.0
3+
version: 1.0.1
44
source: suyog19/software-engineering-process
55
controls:
66
traceability:
@@ -26,7 +26,11 @@ controls:
2626
human_production_boundary:
2727
semantics: locked
2828
enabled: true
29-
prevent_self_approval: true
29+
human_authorization_required: true
30+
manual_promotion_required: true
31+
automation_may_authorize: false
32+
automation_may_promote: false
33+
owner_manual_authorization_may_satisfy: true
3034
required_capabilities:
3135
semantics: extensible
3236
values: [software-developer, ci-automation]
@@ -55,6 +59,7 @@ native_enforcement:
5559
required_status_checks: [engineering-process]
5660
protected_branches: true
5761
production_environment:
58-
required_human_reviewer: true
59-
prevent_self_review: true
60-
62+
manual_human_promotion_required: true
63+
automation_may_promote: false
64+
distinct_human_reviewer_required: false
65+
stronger_multi_human_gate_permitted: true

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "software-engineering-process"
7-
version = "1.0.0"
7+
version = "1.0.1"
88
description = "Technology-neutral engineering policy and assurance platform"
99
readme = "README.md"
1010
requires-python = ">=3.11"
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
"""Software Engineering Policy and Assurance platform."""
22

3-
__version__ = "1.0.0"
4-
3+
__version__ = "1.0.1"

src/engineering_process/evaluation.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ def evaluate(policy_root: Path, manifest: dict, classification: Classification)
4646
"approvals": approvals,
4747
"prohibited_actions": sorted(selected["prohibited_actions"]),
4848
"native_enforcement": core["native_enforcement"],
49+
"human_production_boundary": controls["human_production_boundary"],
50+
"independent_review": controls["independent_review"],
4951
"validation_commands": controls["validation_commands"]["values"],
5052
"not_required": sorted(all_caps - capabilities),
5153
"execution_boundary": "Policy defines WHAT; assistants, humans, CI and native controls own HOW.",
5254
}
53-

tests/conftest.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212

1313
@pytest.fixture
1414
def manifest():
15-
return {"schema_version": 1, "process": {"source": "suyog19/software-engineering-process", "version": "1.0.0", "revision": REV, "profile": "generic"}, "repository": {"name": "example/repo"}, "overrides": {}}
15+
return {"schema_version": 1, "process": {"source": "suyog19/software-engineering-process", "version": "1.0.1", "revision": REV, "profile": "generic"}, "repository": {"name": "example/repo"}, "overrides": {}}
1616

1717

1818
def profile(name):
1919
return load_policy(policy_root(), name)[1]
20-

tests/test_evaluation.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,28 @@ def test_native_capabilities_are_exposed(manifest):
2929
result = classify(policy_root(), profile("generic"), manifest)
3030
native = evaluate(policy_root(), manifest, result)["native_enforcement"]
3131
assert native["protected_branches"] is True
32-
assert native["production_environment"]["prevent_self_review"] is True
32+
production = native["production_environment"]
33+
assert production["manual_human_promotion_required"] is True
34+
assert production["automation_may_promote"] is False
35+
assert production["distinct_human_reviewer_required"] is False
3336

37+
38+
def test_human_boundary_allows_manual_owner_authorization(manifest):
39+
result = classify(policy_root(), profile("generic"), manifest)
40+
obligations = evaluate(policy_root(), manifest, result)
41+
boundary = obligations["human_production_boundary"]
42+
assert boundary["human_authorization_required"] is True
43+
assert boundary["manual_promotion_required"] is True
44+
assert boundary["owner_manual_authorization_may_satisfy"] is True
45+
assert boundary["automation_may_authorize"] is False
46+
assert boundary["automation_may_promote"] is False
47+
48+
49+
def test_fresh_context_review_remains_required(manifest):
50+
result = classify(policy_root(), profile("generic"), manifest)
51+
obligations = evaluate(policy_root(), manifest, result)
52+
assert "independent-review" in obligations["required_capabilities"]
53+
assert "independent-review/v1" in obligations["required_evidence"]
54+
review = obligations["independent_review"]
55+
assert review["fresh_context_required"] is True
56+
assert review["implementation_context_may_issue_verdict"] is False

0 commit comments

Comments
 (0)