Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
09c9ca3
feat: add bitemporal people domain kernel
seonghobae Aug 15, 2026
cbd86b5
merge: refresh foundation baseline
seonghobae Aug 15, 2026
c7c7b61
test: separate durable person identity from effective names
seonghobae Aug 16, 2026
99f40a0
fix: separate person anchor from effective name facts
seonghobae Aug 16, 2026
b3dce34
test: require organization and job domain records
seonghobae Aug 16, 2026
b98f307
feat: model bitemporal organization and job records
seonghobae Aug 16, 2026
f095b06
feat: export organization and job domain records
seonghobae Aug 16, 2026
85ffc72
docs: describe organization and job domain coverage
seonghobae Aug 16, 2026
5c3b341
docs: trace organization and job domain records
seonghobae Aug 16, 2026
3d9b469
docs: record organization and job domain slice
seonghobae Aug 16, 2026
32ef213
test: separate organization and job identity from versions
seonghobae Aug 16, 2026
d017128
fix: normalize organization and job version facts
seonghobae Aug 16, 2026
4d38390
fix: export normalized organization and job versions
seonghobae Aug 16, 2026
e47e787
docs: explain normalized organization and job history
seonghobae Aug 16, 2026
7b72ec1
docs: trace durable organization and job anchors
seonghobae Aug 16, 2026
c8180d0
docs: record normalized organization and job history
seonghobae Aug 16, 2026
c89e612
test: reproduce unsafe assignment numeric and error behavior
seonghobae Aug 16, 2026
4b133ca
fix: fail closed on unsafe assignment allocations
seonghobae Aug 16, 2026
86405c4
test: align allocation overlap assertion with safe error contract
seonghobae Aug 16, 2026
f1fe180
test: require installed-wheel quality evidence
seonghobae Aug 16, 2026
9d9bfcb
build: pin wheel backend for artifact smoke
seonghobae Aug 16, 2026
9d830e8
build: prove typed wheel installs outside source tree
seonghobae Aug 16, 2026
2ce30f4
test: require explicit person-anchor lifecycle boundary
seonghobae Aug 16, 2026
3eebded
docs: define person-anchor recorded lifecycle ownership
seonghobae Aug 16, 2026
0f257b5
test(domain): require exact-head workflow evidence
seonghobae Aug 16, 2026
ab7720f
fix(ci): bind domain quality to exact pull request head
seonghobae Aug 16, 2026
0179b8e
test: reject superseded foundation references
seonghobae Aug 16, 2026
d1f0268
test: cover stale protected-branch wording
seonghobae Aug 16, 2026
87b3144
docs: point domain stack at canonical foundation
seonghobae Aug 16, 2026
8e6d7c4
docs: describe protected default branch generically
seonghobae Aug 16, 2026
e747eab
chore: refresh domain stack integrity manifest
seonghobae Aug 16, 2026
e534a1e
fix: synchronize domain integrity manifest
seonghobae Aug 16, 2026
1cfba68
test: specify bitemporal historical resolution
seonghobae Aug 16, 2026
aaf29b4
test: make temporal failure contracts explicit
seonghobae Aug 16, 2026
0911dfd
feat: fail closed on ambiguous temporal facts
seonghobae Aug 16, 2026
bc6e295
feat: resolve bitemporal historical facts
seonghobae Aug 16, 2026
60df35e
feat: export temporal historical resolver
seonghobae Aug 16, 2026
1962a84
docs: explain bitemporal historical resolution
seonghobae Aug 16, 2026
25dd682
docs: record historical query capability
seonghobae Aug 16, 2026
edfcee2
docs: trace historical resolution evidence
seonghobae Aug 16, 2026
565854c
chore: refresh temporal resolution integrity manifest
seonghobae Aug 16, 2026
42a1502
test: reject stale protected-main wording in stack
seonghobae Aug 16, 2026
6b68189
docs: follow protected default branch truth
seonghobae Aug 16, 2026
c707ae0
chore: refresh stack governance manifest
seonghobae Aug 16, 2026
08c96b7
fix: bound candidate relink errors
seonghobae Aug 16, 2026
cf557c9
fix: make bitemporal resolution identity-aware
seonghobae Aug 16, 2026
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
51 changes: 51 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Domain Quality

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

concurrency:
group: orgmetra-quality-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
domain-quality-matrix:
name: domain-quality (${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
env:
PIP_DISABLE_PIP_VERSION_CHECK: "1"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
with:
python-version: ${{ matrix.python-version }}
- name: Install hash-locked quality dependency
run: >-
python -m pip install
--only-binary=:all:
--require-hashes
-r requirements/ci.txt
- name: Verify domain and repository contracts
run: ./scripts/run_domain_quality.sh

domain-quality:
name: domain-quality
needs: domain-quality-matrix
if: always()
runs-on: ubuntu-latest
steps:
- name: Require every supported Python lane
run: |
echo "domain-quality-matrix result=${{ needs.domain-quality-matrix.result }}"
test "${{ needs.domain-quality-matrix.result }}" = "success"
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Build Orgmetra as a commercial-grade, evidence-centered HRIS and HCM platform th

## Documentation rules

Keep README, PRD, TRD, ARCHITECTURE, DATA_MODEL, ERD, UML, API_CONTRACT, SECURITY, THREAT_MODEL, TEST_STRATEGY, OPERABILITY, TRACEABILITY, ADRs, doctoring references, AGENTS, CLAUDE, and CHANGELOG current with code. Distinguish shipped protected-main truth from active PRs, accepted architecture, planned work, research-only work, superseded work, and out-of-scope work.
Keep README, PRD, TRD, ARCHITECTURE, DATA_MODEL, ERD, UML, API_CONTRACT, SECURITY, THREAT_MODEL, TEST_STRATEGY, OPERABILITY, TRACEABILITY, ADRs, doctoring references, AGENTS, CLAUDE, and CHANGELOG current with code. Distinguish shipped protected default branch truth from active PRs, accepted architecture, planned work, research-only work, superseded work, and out-of-scope work.

## Quality rules

Expand Down
4 changes: 4 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ The foundation can start as a monorepo with separately deployable services. Serv
## Security posture

Access is tenant, actor, purpose, resource, and lifetime scoped. High-impact decisions require evidence, explicit decision records, and human accountability. LLM outputs are draft evidence only.

## Active implementation slice: bitemporal domain kernel

`packages/orgmetra-domain` implements framework-independent invariants for effective/system time, distinct HRIS records, multiple assignments, and candidate-worker continuity. It has no persistence or transport dependency and can be embedded by future services. This section describes active-PR work until merged into the protected default branch.
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,31 @@ All notable changes to Orgmetra will be documented in this file.

### Added

- Independently importable `orgmetra-domain` package for bitemporal HRIS invariants.
- Deterministic business-time/knowledge-time historical fact resolution that fails closed on ambiguous overlapping versions.
- Durable organization-unit and job-profile anchors with separate bitemporal version records so Organization, Job, Position, and Assignment remain distinct HRIS concepts.
- Multiple-membership assignment allocation validation with half-open effective intervals.
- Append-only, idempotent candidate-to-worker linkage.
- Hash-locked Python 3.11-3.14 quality workflow with exact 100% production statement/branch coverage and public docstring checks.
- Foundation product baseline for Orgmetra as evidence-centered HRIS/HCM.
- CWL federated integration boundary map.
- Bitemporal HRIS data contract.
- Core ERD, UML, PRD, TRD, user stories, storyboard, wireframes, Storybook inventory, security, test, and operability baseline.

### Changed

- Organization and job mutable descriptions now live in version records rather than durable identity anchors, preserving normalized history and stable position references.
- Effective and system-recorded intervals are non-empty half-open periods; equal start/end bounds are rejected.
- Assignment portfolio validation now requires an explicit timezone-aware knowledge time and excludes superseded recorded versions before calculating FTE overlap.
- Historical fact resolution now scopes visibility and ambiguity to one caller-selected durable identity instead of conflating simultaneously visible facts from different people or entities.

### Security

- Purpose-bound PII access contract.
- LLM output constrained to draft evidence.
- No direct cross-service database access.
- Candidate-to-worker relink failures now return a bounded adapter-safe message with no candidate or person identifiers.

### Notes

- The protected default branch contains only the minimal bootstrap commit. This baseline is proposed through `feat/foundation-product-baseline` and becomes shipped truth only after review and merge.
- The protected default branch contains only the minimal bootstrap commit. PR #8 is the canonical foundation baseline; this domain slice remains stacked behind it and becomes shipped truth only after dependency-ordered review, fresh exact-head checks, and merge.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ Job evidence
- `docs/adr/README.md`
- `docs/doctoring/REFERENCES.md`

## Implementation slices

- `packages/orgmetra-domain`: bitemporal people, employment, position, assignment, and candidate-worker invariants.
- `.github/workflows/quality.yml`: pinned Python 3.11-3.14 quality matrix with an aggregate required check.

## Status

Foundation phase. The protected default branch contains the minimal repository bootstrap; this product baseline is proposed through a reviewed pull request and must not be treated as shipped behavior before merge.
The foundation baseline is proposed in PR #8 against the protected default `bootstrap` branch. This bitemporal domain kernel is the next stacked implementation PR and is not protected default-branch truth until PR #8 and this PR merge in dependency order with fresh exact-head evidence.
17 changes: 17 additions & 0 deletions docs/TEST_STRATEGY.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,20 @@ Required evidence for any Orgmetra-owned mathematical compute:
- Exact-value table for every chart.
- Permission-denied states.
- High-risk confirmation preview.

## Active domain-kernel test evidence

The stacked implementation runs the behavioral domain suite plus repository-contract tests. It proves:

- reversed and ambiguous bitemporal intervals fail closed;
- half-open boundaries behave correctly;
- valid values normalize without silently accepting blanks;
- assignment allocation is evaluated at an explicit timezone-aware knowledge time so superseded recorded versions do not inflate current FTE;
- multiple assignments visible at that coordinate can sum to one but cannot exceed one during overlap;
- adjacent assignments do not overlap;
- people are validated independently;
- historical resolution scopes ambiguity to the requested durable identity while ignoring simultaneously visible facts for other identities;
- candidate-worker registration is idempotent, cannot relink a candidate to a different person, and does not leak candidate/person UUIDs on conflict;
- owned production statement and branch coverage are exactly 100%;
- public modules, classes, and functions have docstrings;
- CI actions are commit-pinned and dependencies are hash-locked.
9 changes: 6 additions & 3 deletions docs/TRACEABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

| Requirement | Architecture | Data object | Test family | ADR |
|---|---|---|---|---|
| Separate person/employment/job/position/assignment | Core bounded contexts | `person_record`, `employment_record`, `job_profile`, `position_record`, `assignment_record` | schema/domain tests | ADR-0001 |
| Separate person/employment/organization/job/position/assignment | Core bounded contexts + `orgmetra-domain` active PR | `person_record`, `employment_record`, `organization_unit`, `job_profile`, `position_record`, `assignment_record` | `test_domain.py` record and assignment tests | ADR-0001 |
| Durable organization/job identity with bitemporal descriptive history | People Core + `OrganizationUnitRecord` / `OrganizationUnitVersionRecord` / `JobProfileRecord` / `JobProfileVersionRecord` active PR | `organization_unit`, `organization_unit_version`, `job_profile`, `job_profile_version` | `RecordValidationTests` | ADR-0001, ADR-0003 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub mergeability is CONFLICTING. This stacked tree still vendors the pre-tenant schema snapshot (display_name on person_record, no version tables) and hashes it. Live foundation already has tenant_record, person_name_record, organization_unit_version, and job_profile_version.

TRACEABILITY must name the live tables this kernel can actually implement. After rebase, rewrite the person-lifecycle contract test and the integrity manifest. Add a contract that domain types remain implementable against the live schema (numeric(5,4), tenant FKs).

Next action: rebase onto current #8 after it merges. Do not transfer predecessor checks or approvals.

| Effective/system time | Bitemporal HRIS + `BitemporalPeriod` active PR | `effective_from`, `effective_to`, `recorded_from`, `recorded_to` | `BitemporalPeriodTests` | ADR-0003 |
| Identity-scoped effective-known historical resolution | Bitemporal HRIS + `resolve_bitemporal_fact` active PR | version records exposing durable identity + `BitemporalPeriod` | `BitemporalResolutionTests` retroactive-correction, mixed-identity, no-match, aware-time and same-identity ambiguity cases | ADR-0003, ADR-0004 |
| Assignment allocation at knowledge time | People Core + `validate_assignment_portfolio` active PR | bitemporal `assignment_record` versions | `AssignmentSecurityRegressionTests` superseded-version and aware-time cases; `AssignmentPortfolioTests` overlap cases | ADR-0001, ADR-0003 |
| Candidate-worker continuity | People Core + `CandidateWorkerRegistry` active PR | `candidate_worker_link` | `CandidateWorkerRegistryTests`, including identifier-leakage regression | ADR-0001 |
| Federated CWL integration | Integration Hub | `external_reference` conceptual | adapter contract tests | ADR-0002 |
| Effective/system time | Bitemporal HRIS | `effective_from`, `recorded_from` | bitemporal tests | ADR-0003 |
| Evidence-backed decisions | Talent Acquisition | `selection_decision`, `evidence_reference` | decision evidence tests | ADR-0001 |
| Predictive validity loop | Workforce Validation | `validity_study`, `criterion_observation` | validation registry tests | ADR-0001 |
| Purpose-bound PII access | Security architecture | field policy conceptual | authorization matrix tests | ADR-0003 |
14 changes: 14 additions & 0 deletions docs/TRD.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,17 @@ Adapters must fail closed, never log credentials, and never promote external dat
- Criterion and validation registry tests.
- Integration adapter fake-server tests.
- Accessibility tests for role workspaces.

## 8. Active implementation evidence

The stacked bitemporal domain slice implements these P0 contracts as a pure Python package:

- half-open effective and recorded intervals;
- timezone-aware system timestamps;
- distinct person, employment, and position records;
- multiple simultaneous assignments with total allocation no greater than one per person;
- append-only candidate-worker linkage;
- a PEP 561 typed-package marker;
- Python 3.11-3.14 CI, exact 100% production statement/branch coverage, and public docstring validation.

Psychometric and mathematical production arithmetic is intentionally absent from this package and remains Rust-first in its owning service.
34 changes: 34 additions & 0 deletions docs/adr/0004-framework-independent-domain-kernel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# ADR 0004: Framework-independent domain kernel

## Status

Proposed in active implementation PR.

## Context

Core HRIS invariants must be reusable by standalone services, a modular monorepo, tests, migration workers, and future API adapters without importing a web framework or database driver. These invariants are non-mathematical and do not require the Rust psychometric compute policy.

ADR 0003 requires effective/business time and system-recorded time to remain independently reconstructable. A durable person identity is different from a mutable HR fact: the domain package exposes an identity-only `PersonRecord`, while creation and retirement knowledge time are persistence-owned lifecycle metadata. The authoritative persistence contract must therefore retain `recorded_from` and `recorded_to` for the person anchor even though those columns are not duplicated as mutable attributes on the in-memory identity value. Adapters that load or persist a person anchor must carry that lifecycle metadata in their repository envelope rather than silently dropping it.

## Decision

Implement bitemporal people, employment, position, assignment, and candidate-worker invariants in the independently installable `orgmetra-domain` Python package. Keep persistence, authorization, transport, and external integrations outside the package. Include a PEP 561 marker and exact coverage/docstring gates.

Keep durable identity anchors intentionally small. `PersonRecord` contains only the opaque durable identity; persistence owns the recorded lifecycle of that identity. Mutable person names and other effective-dated facts use explicit version records with `BitemporalPeriod`. Repository adapters are responsible for preserving the anchor's system-recorded lifecycle alongside the identity, and repository-contract tests require both lifecycle columns to remain present in the authoritative schema.

## Consequences

- Domain behavior is testable without infrastructure.
- Future services can embed the same invariant layer.
- Database constraints must mirror these rules transactionally.
- Person-anchor creation/retirement history remains reconstructable without turning the durable identity object into a mutable fact record.
- A repository adapter that omits the person anchor's `recorded_from` or `recorded_to` violates this ADR even if an identity-only `PersonRecord` can still be constructed.
- Psychometric and mathematical computation remains Rust-first and is not added to this package.

## Acceptance evidence

- Behavioral RED/GREEN tests for every invariant.
- Repository-contract proof that the person persistence record retains `recorded_from` and `recorded_to` while the domain anchor remains identity-only.
- Exact 100% production statement and branch coverage.
- Python 3.11-3.14 CI.
- Installed-wheel smoke and `py.typed` presence verification before release.
1 change: 1 addition & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
| 0001 | Accepted baseline | Orgmetra owns authoritative HRIS records |
| 0002 | Accepted baseline | Federated CWL integration boundaries |
| 0003 | Accepted baseline | Bitemporal HRIS data contract |
| 0004 | Proposed in active PR | Framework-independent domain kernel |
Loading