Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
78e0923
test(position-reporting): define durable bitemporal persistence contract
seonghobae Aug 24, 2026
df8d8b4
ci(position-reporting): add exact-head persistence quality gate
seonghobae Aug 24, 2026
2092591
feat(position-reporting): persist governed bitemporal relationships
seonghobae Aug 24, 2026
af4a561
docs(position-reporting): record persistence architecture decision
seonghobae Aug 24, 2026
c904380
docs(position-reporting): add persistence traceability
seonghobae Aug 24, 2026
d499a24
docs(position-reporting): record primary persistence references
seonghobae Aug 24, 2026
2e421d8
test(position-reporting): make self and cycle regressions independent
seonghobae Aug 24, 2026
8657e65
test(position-reporting): require immutable review-evidence binding
seonghobae Aug 24, 2026
566b745
ci(position-reporting): gate immutable review binding
seonghobae Aug 24, 2026
fc1fb92
fix(position-reporting): bind review evidence into immutable applicat…
seonghobae Aug 24, 2026
affa260
test(position-reporting): bind application event to reviewed evidence
seonghobae Aug 24, 2026
cfef3e2
test(position-reporting): verify exact application event digest binding
seonghobae Aug 24, 2026
0e09e35
docs(position-reporting): bind review digest to application audit
seonghobae Aug 24, 2026
a5bff30
docs(position-reporting): trace immutable review and application binding
seonghobae Aug 24, 2026
f784fd7
test(position-reporting): prove concurrent cycle prevention
seonghobae Aug 24, 2026
6992305
ci(position-reporting): gate concurrent graph mutation safety
seonghobae Aug 24, 2026
df13397
fix(position-reporting): serialize tenant graph mutations before cycl…
seonghobae Aug 24, 2026
2e948a0
docs(position-reporting): record concurrent graph serialization
seonghobae Aug 24, 2026
5c6cc23
docs(position-reporting): trace concurrent cycle prevention
seonghobae Aug 24, 2026
c5dd5e5
docs(position-reporting): cite concurrency snapshot and advisory-lock…
seonghobae Aug 24, 2026
8f0a874
test(position-reporting): require staffable endpoint coverage
seonghobae Aug 24, 2026
facfff9
fix(position-reporting): require staffable endpoint coverage
seonghobae Aug 24, 2026
5b9833a
docs(position-reporting): bind persistence to staffable endpoints
seonghobae Aug 24, 2026
760b0cd
docs(position-reporting): trace endpoint coverage repair
seonghobae Aug 24, 2026
4544d8a
docs(position-reporting): cite multirange coverage semantics
seonghobae Aug 24, 2026
6161190
test(position-reporting): restore concurrency fixture coverage
seonghobae Aug 24, 2026
2af2540
test(position-reporting): reject mismatched audit reason evidence
seonghobae Aug 24, 2026
ef8c777
fix(position-reporting): bind governed audit reason
seonghobae Aug 24, 2026
8ede14c
docs(position-reporting): trace governed audit reason binding
seonghobae Aug 24, 2026
c35ad11
docs(position-reporting): map wrong-reason regression
seonghobae Aug 24, 2026
f8b72ec
fix(position-reporting): harden persistence boundaries
seonghobae Aug 28, 2026
a367b4e
test(position-reporting): remove concurrency winner assumption
seonghobae Aug 28, 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
96 changes: 96 additions & 0 deletions .github/workflows/position-reporting-persistence-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Position Reporting Persistence Quality

on:
pull_request:
branches:
- develop
- feat/position-reporting-hierarchy
paths:
- "database/migrations/0020_position_reporting_relationship.sql"
- "tests/test_position_reporting_persistence_postgres.sh"
- "tests/test_position_reporting_review_binding_postgres.sh"
- "tests/test_position_reporting_concurrency_postgres.sh"
- "docs/adr/0106-position-reporting-persistence.md"
- "docs/traceability/position-reporting-persistence.md"
- "docs/doctoring/position-reporting-persistence-references.md"
- ".github/workflows/position-reporting-persistence-quality.yml"
workflow_dispatch:

permissions:
contents: read

concurrency:
group: position-reporting-persistence-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
postgres_contract:
name: Governed position-reporting persistence contract
runs-on: ubuntu-latest
timeout-minutes: 10
services:
postgres:
image: postgres:16.14@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20
env:
POSTGRES_USER: orgmetra
POSTGRES_PASSWORD: orgmetra
POSTGRES_DB: orgmetra
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U orgmetra -d orgmetra"
--health-interval 5s
--health-timeout 5s
--health-retries 10
env:
DATABASE_URL: postgresql://orgmetra:orgmetra@localhost:5432/orgmetra
steps:
- name: Checkout exact candidate
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- name: Prove exact candidate checkout
env:
ORGMETRA_EXPECTED_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: test "$(git rev-parse HEAD)" = "$ORGMETRA_EXPECTED_HEAD_SHA"
- name: Print deterministic persistence provenance
run: |
python - <<'PY'
import hashlib
import json
from pathlib import Path

required = [
"tests/test_position_reporting_persistence_postgres.sh",
"tests/test_position_reporting_review_binding_postgres.sh",
"tests/test_position_reporting_concurrency_postgres.sh",
".github/workflows/position-reporting-persistence-quality.yml",
]
optional = [
"database/migrations/0020_position_reporting_relationship.sql",
"docs/adr/0106-position-reporting-persistence.md",
"docs/traceability/position-reporting-persistence.md",
"docs/doctoring/position-reporting-persistence-references.md",
]
rows = []
for path_text in required + [path for path in optional if Path(path).is_file()]:
data = Path(path_text).read_bytes()
rows.append({
"path": path_text,
"sha256": hashlib.sha256(data).hexdigest(),
"bytes": len(data),
"lines": len(data.decode("utf-8").splitlines()),
})
print(json.dumps(rows, separators=(",", ":")))
PY
- name: Run position-reporting persistence regressions
run: bash tests/test_position_reporting_persistence_postgres.sh
- name: Verify immutable human-review binding
run: bash tests/test_position_reporting_review_binding_postgres.sh
- name: Verify concurrent cycle prevention
run: bash tests/test_position_reporting_concurrency_postgres.sh
- name: Require clean checkout
run: |
git diff --exit-code
test -z "$(git status --porcelain)"
2 changes: 1 addition & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ The initial deployment may share one physical PostgreSQL cluster. Logical isolat
| Service identifier | Owned schema and representative tables | Database role |
|---|---|---|
| `people_core` | `people_core`: person, name, employment, assignment, compensation, and candidate-worker linkage records | `people_core_role` |
| `organization_core` | `organization_core`: organization units and position records | `organization_core_role` |
| `organization_core` | `organization_core`: organization units, position records, and Position reporting relations | `organization_core_role` |
| `job_architecture` | `job_architecture`: job profiles, publication evidence, and persisted `job_analysis_snapshot` / task / KSAO rows | `job_architecture_role` |
| `talent_acquisition` | `talent_acquisition`: candidate profiles, selection decisions, and decision evidence | `talent_acquisition_role` |
| `performance_management` | `performance_management`: criterion blueprints and observations | `performance_management_role` |
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ All notable changes to Orgmetra will be documented in this file.

- Accepted ADRs 0001–0003 now include buyer-facing Context, Decision, and Consequences grounded in verified ISO 30400:2022, ISO 30414:2025, Uniform Guidelines (29 C.F.R. Part 1607), SIOP (2018), OpenAPI Specification v3.2.0, OpenID Connect Core 1.0 errata set 2, CloudEvents v1.0.2, Jensen and Snodgrass (1999), Snodgrass (1999), and Allen (1983) records already listed in `docs/doctoring/REFERENCES.md`. ADRs 0004 and 0005 gained APA 7th References pointers to that same bibliography without changing their Decision bodies.
- Active-PR governed Job Analysis persistence/API on the canonical `JobAnalysisSnapshot` model: migration `0013_job_analysis_snapshot.sql` stores immutable tenant-scoped snapshot, Task, KSAO, Task–KSAO, FJA and write-command evidence; `POST /v1/tenants/{tenant_record_id}/job-analysis-snapshots` and matching GET enforce purpose-bound Keyverse scope, authenticated-principal actor authority, bounded/strict JSON handling, transactional Idempotency-Key serialization, parent-scope fail-closed integrity, forced RLS, and atomic audit/outbox evidence. ADR 0014 records the persistence decision while ADR 0007 remains the domain/evidence authority; validated evidence still requires accountable human review and non-LLM provenance, and the service does not make a high-impact employment decision.
- Active-PR #106 Position-to-Position reporting persistence: normalized bitemporal solid-line relationship anchor/version tables with staffable endpoint coverage, tenant isolation, cycle prevention under concurrent writes, immutable human-review/application audit binding, history/TRUNCATE guards, trusted trigger search paths, and reserved UUID sentinel checks. It remains Draft stacked on PR #94 and is not protected-branch truth.
- Active-PR `orgmetra_selection_review` packet for PII-minimized, evidence-bound human selection review: canonical operational tenant identity, UUID-backed opaque candidate/Job/sealed-evidence/reviewer references, explicit purpose/reason/evidence version, deterministic canonical JSON and SHA-256 correlation, mandatory human decision state, redacted packet repr, and provenance-paired model evidence that remains `untrusted_draft`, with exact 100% owned statement and branch coverage required by its quality gate.
- Active performance-criterion scope hardening: `criterion_observation_scope_guard` rejects criterion outcomes for a Job the worker did not effectively hold at the observation date, observations before the relevant assignment, and observations outside the referenced performance cycle while preserving valid multiple-assignment cases and existing bitemporal correction semantics. The guard evaluates current-recorded facts, derives the date coordinate from `observed_at` in UTC so session `TimeZone` cannot alter the result, uses a trusted function search path, and adds no PII or automated employment decision authority. The Foundation PostgreSQL contract also rejects a closed `recorded_to` on each time-coordinate lookup and proves UTC midnight plus non-UTC session `TimeZone` boundaries.
- Bitemporal tenant-scoped organization hierarchy validation that rejects visible indirect parent cycles and reuses single-valued recorded-time reconstruction before graph traversal.
Expand Down
Loading