Skip to content

feat(process): open-region slot — applies_to invariant scoping + open_region marker#425

Merged
aleskalfas merged 4 commits into
mainfrom
feat/418-implement-the-open-region-slot
Jul 1, 2026
Merged

feat(process): open-region slot — applies_to invariant scoping + open_region marker#425
aleskalfas merged 4 commits into
mainfrom
feat/418-implement-the-open-region-slot

Conversation

@aleskalfas

Copy link
Copy Markdown
Owner

Closes #418.

What

Ships the open-region slot's shape contract + engine (Feature #416 under EPIC #237), implementing accepted COR-040 per accepted engine-strategy ADR-036. The whole engine novelty is a position-keyed filter in evaluate_invariants: an invariant may carry an optional applies_to (a state id); scoped invariants evaluate/surface only when the subject's resolved position matches, unscoped stay process-wide (COR-035 unchanged). A state.open_region marker is declared in the shape (inert to the engine — no new node kind). Boundary-enforcement is exit-gate predicate composition (no invariant→move-blocking); a shut exit is an ordinary closed gate.

Additive only — existing processes validate byte-unchanged; no migration owed. Includes the minor version bump 1.133.0 → 1.134.0.

Doc impact

.pkit/process/README.md (shape reference) updated: open_region + applies_to added to the state / invariant skeletons; the open-region and per-state-scoping / boundary-enforcement rows flipped from deferred to core, describing enforcement as gate composition (report-only preserved). No other doc surface affected.

Test plan

New tests/test_process_open_region_engine.py + tests/test_process_open_region_schema.py cover: unscoped-unchanged (in/out of region), scoped-in-region evaluated, scoped-out-of-region not-surfaced, scoped-under-indeterminate not-applicable, status/validate filtering (narrative + --json), violated-region-invariant-alongside-shut-exit rendering, exit opening when met, read-only. Full suite: 4227 pass. pkit migrations check-diff clean; schemas / decisions validate pass.

Reviews

  • Rule COR-040 (accepted) — reviewed by critic + architect.
  • Engine strategy ADR-036 (accepted) — authored by architect; the implementation matched it verbatim (no adjustments).

Scope

Task #418 (engine + shape + ADR) under Feature #416. Next: #419 grounds the slot on trip-planning build (DEC-014 → accepted).

🤖 Generated with Claude Code

aleskalfas and others added 4 commits July 1, 2026 17:48
Sibling to ADR-022/023. Records the engine strategy for COR-040: region-scoped
invariants are an `applies_to` filter on evaluate_invariants keyed on the
resolved position; boundary-enforcement is exit-gate predicate composition (no
invariant→move-blocking); a shut exit is a closed gate, not a blocked overlay;
and the compound "(predicate) AND (cross-authority artifact)" exit is NOT one
gate — the sign-off stays an authorisation-artifact gate, the conjunction lives
in the wrapper (ADR-023 primitive), because folding it into a deterministic
predicate loses the COR-033-P4 authorship guarantee. Authored by the architect
agent; supersedes nothing.

Tracked by #418. Status: proposed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Approved by Aleš Kalfas (authorised the architect→software-engineer chain);
architect gave clean clearance (advisory, no escalation). Unblocks the engine
+ shape implementation on #418.

Status: accepted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…_region marker

Implements COR-040 / ADR-036: an invariant may carry an optional `applies_to`
state scope, and a state may be marked `open_region: true`. Both additive —
existing processes declare neither and validate byte-unchanged.

Engine (evaluate_invariants) filters each invariant by `applies_to` against
resolve_position().state_id: unscoped stays process-wide (COR-035 unchanged);
scoped is evaluated/surfaced only when the subject's resolved position is the
region; scoped under another region or an indeterminate position is
not-applicable (not evaluated, not surfaced). Fail-closed on an indeterminate
scoped check is unchanged. The filter reuses the existing PredicateRunner + cache
and reads position once. No new gate kind, no new blocked reason, no
invariant→move-blocking primitive — precheck_transitions, evaluate_gate, and
evaluate_blocked are byte-unchanged; the region exit is an ordinary
deterministic / authorisation-artifact gate. Status/validate surface the
filtered set through the existing "Invariant violations" + "Legal moves"
surfaces (narrative + --json), so a region-scoped violation renders alongside
the shut exit gate as the reason the subject cannot leave.

Shape reference (process README) flips the open-region and applies_to /
boundary-enforcement rows from deferred to core.

No migration owed (pure additive; check-diff reports no trigger).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Surface change (PRJ-002): new shape fields (invariant.applies_to, state.open_region)
+ engine behaviour + a new convention adopters follow. Broadens the adapter's
requires_backbone ceiling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@aleskalfas

Copy link
Copy Markdown
Owner Author

Reviewer agent (local, reviewer): APPROVED

Reviewed PR #425 (feat/418-implement-the-open-region-slot, closes #418) against the pm capability's conventions. All criteria pass; nothing blocking.

Findings

  • Branch shapefeat/418-implement-the-open-region-slot matches ^(feat|…)/[0-9]+-<slug>$ from git-conventions.yaml. Pass.
  • Branch-type / issue-type alignment — closing issue [Task] Implement the open-region slot in the shape contract + engine, and author the engine-strategy ADR #418 carries type:feature; pr_type_mapping maps feature → feat, matching the branch's feat segment. Pass.
  • PR title Conventional Commitsfeat(process): open-region slot — applies_to invariant scoping + open_region marker parses as <type>(<scope>): <desc> with feat in the accepted PR-title set (decision correctly not used as a title type, per the schema's branch/title asymmetry note). Pass.
  • PR-title type matches issue typefeat derives from type:feature per pr_type_mapping. Pass.
  • Issue classification complete[Task] Implement the open-region slot in the shape contract + engine, and author the engine-strategy ADR #418 carries type:feature, priority:Medium, workstream:workflow (plus state:in-progress). All three axes present per [project-management:DEC-012-classification-axes]. Pass.
  • PR body links closing issueCloses #418. present and closingIssuesReferences populated. Body also carries ## Doc impact and ## Test plan with authored items (no empty-checkbox skeleton). Pass.
  • Surface-change discipline (COR-010) — schema changes to process.schema.json are strictly additive (open_region, applies_to added; schema_version stays 1; no renames/removals), the PR states pkit migrations check-diff is clean, and the version bump 1.133.0 → 1.134.0 with the adapter's requires_backbone ceiling broadened is consistent with a no-migration additive surface change. Pass.
  • No-shared-files (COR-001) — this is project-kit's own source repo (self-hosting); edits to .pkit/ core trees are owner edits here, not adopter edits to installed core. Pass.

Note (non-blocking): the ADR-036 commit body shows status authored as proposed then flipped to accepted in a follow-up commit within the same change-set; the merged artifact frontmatter reads status: accepted, so the acceptance gate is satisfied at merge time.

@aleskalfas aleskalfas merged commit 02606df into main Jul 1, 2026
1 check passed
@aleskalfas aleskalfas deleted the feat/418-implement-the-open-region-slot branch July 1, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task] Implement the open-region slot in the shape contract + engine, and author the engine-strategy ADR

1 participant