Skip to content

docs: maintain durable product-technical gap baseline - #100

Draft
seonghobae wants to merge 213 commits into
developfrom
docs/product-technical-gap-baseline
Draft

docs: maintain durable product-technical gap baseline#100
seonghobae wants to merge 213 commits into
developfrom
docs/product-technical-gap-baseline

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Scope

Canonical single-writer lane for docs/product-technical-gap-baseline.md. The baseline records durable product/domain/control-plane truth and causal dependency order; it is not merge authorization and does not freeze volatile PR heads, run IDs, queue snapshots, or review state into the document.

Current durable baseline

The baseline at c0a40a4d598635cc1056a29451a4707d00c613c5 remains code-current at the durable-contract level after workflow owner #161 integrated as protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f. It already records #63 shared HRIS-kernel ownership, #64-before-#65 owner order, protected-owner adoption before consumer evidence, Assignment dependency order, ruleset controls, and the release gate.

#211#214 refine the shared trust boundary. #215#228 refine durable People/hire scalar/container and command/result boundaries. #229 requires ordinary generic People results and confirmed-hire results to remain bound to authoritative pre-port target identities. #246 records the necessary idempotent-replay qualification for generic Employment/Position/Assignment: their published semantic digest deliberately excludes generated record IDs, so an identical same-key retry may return the first committed identity instead of the retry's fresh generated identity only when the persistence result carries exact replay evidence and the application independently recomputes the same semantic command digest. Unexplained foreign results remain fail-closed; confirmed-hire remains exact-identity-bound because its materialization identities are part of that route's command contract. #230 detaches direct PostgreSQL commands; #231 completes application-input ownership before purpose-bound authorization; #232 requires exact built-in Assignment allocation text. #233 closes a public-contract inconsistency by making the parser and published OpenAPI reject zero while retaining the authoritative Assignment allocation domain (0, 1.0000]; deterministic manifest evidence is resealed. These are refinements of the existing durable application/API trust-boundary and idempotency invariants, not new HR aggregates, so leaf SHAs and run IDs remain PR/Issue metadata rather than baseline-body data.

A distinct durable buyer/scientific gap remains #234: protected architecture assigns validity-study registry/scientific evidence ownership to workforce_validation, while protected implementation still lacks the complete owner API and durable owner-table adoption. Draft #235 establishes the independent owner application read boundary from protected develop; #236 makes retained persisted study evidence structurally immutable; #237 applies the same structural-immutability requirement to authenticated principal evidence before purpose-bound authorization. #238 corrects the PostgreSQL role-isolation model: a NOLOGIN schema owner cannot rely on ALTER ROLE ... SET search_path for later SET ROLE runtime isolation, because PostgreSQL applies role defaults at login. #239 adds the complementary constructor-bypass invariant for identity evidence: exact tuple-backed principal type alone is insufficient because low-level tuple.__new__ can bypass ValidationPrincipal.__new__; the owner read boundary must reconstruct/revalidate stored tenant/actor/scope evidence before Keyverse request construction/evaluation. #240 adds the repository-capability invariant exposed by the earlier review graph: runtime Protocol shape alone is not proof of a callable repository dependency, and dependency checking itself must not execute a caller-controlled descriptor before authorization. #241 extends retained-evidence hardening to the data projection by making ValidityStudyView structurally immutable. #242 narrows the ordinary public constructor surface, but does not treat constructor exclusivity or the Python runtime type as proof that authorization occurred; low-level tuple fabrication remains possible and consequential consumers must re-authorize and re-resolve authoritative state. #243 adds the nested-identity invariant: an immutable outer value object is still unsafe if it retains a mutable UUID object alias. Canonical identity authority must be reduced to interpreter-immutable scalar evidence, public UUIDs reconstructed fresh, and executable repository calls must receive detached UUID objects while post-port target verification remains bound to an immutable pre-port snapshot. #244 adds the ingress-scalar invariant: exact UUID outer type is still insufficient if its internal int slot was forged; the boundary must read the payload once, prove exact built-in int before any sentinel/range/equality behavior, and only then store the validated scalar. #245 completes the ordinary issuance-surface cleanup by removing an unconditional module-level projection issuer. #249 closes the remaining checked-versus-used capability gap: inertly validating a repository member before authorization is insufficient if the authorized path later performs a fresh dynamic attribute lookup. The exact ordinary repository function accepted before authorization must be the same function directly invoked afterward; caller-controlled __getattribute__ or descriptor machinery cannot be allowed to substitute a new executable capability after the access decision. #253 completes the concrete-dependency side of that rule: an inherited Protocol/interface declaration is still a runtime function and can satisfy a function-type gate even though no repository implementation exists, so the canonical interface placeholder itself must be rejected before authorization rather than treated as a concrete executable dependency.

#254 adds the Foundation provenance invariant exposed by a real hosted RED: executing a root PostgreSQL acceptance contract from the canonical Foundation workflow is not enough. Every such executable contract must also be registered in both canonical required-file inventories—Node REQUIRED_FILES and Python REQUIRED—and appear in the deterministic manifest.json exact path/hash/bytes/lines seal. A missing inventory entry or stale seal is a real acceptance failure; the repair is to register and reseal the exact artifact, not exempt discovery, remove execution, weaken the manifest path-set equality check, or lower coverage/security gates. #255 adds the complementary exact retained-policy-scalar coverage invariant: an immutable frozenset is not sufficient if one contained field is a caller-defined executable str subtype. The Workforce Validation boundary must reject non-exact policy-field strings before authorization comparison/hashing/persistence, and 100% coverage must execute that fail-closed branch rather than delete or weaken it. Volatile commit/run identifiers remain in #235/#254/#255 metadata rather than the baseline body.

#235 keeps workforce_validation_role as deny-default migration/schema-owner authority only, proves actual SET ROLE behavior in PostgreSQL acceptance, revalidates principal storage before authorization, binds the exact validated owner repository function across authorization, rejects the inherited Protocol declaration as a non-concrete capability, stores UUID authority without retained mutable aliases, validates UUID internal payloads before executable comparison, exposes no ordinary unconditional view issuer, and explicitly treats the returned ValidityStudyView as data rather than reusable authority. A distinct least-privilege runtime role plus schema-qualified relations/function-level search-path controls remain part of the durable adapter increment. The service test lane and owner-schema PostgreSQL contract are admitted to canonical Foundation without weakening hash/coverage controls, and #254 requires the executable contract to be represented in both provenance inventories plus the exact manifest seal. Current #235 exact head is dd95dd7256f37aab2c4f26aa1fb43e8c867f4e4d: Foundation and SAST are terminal GREEN, including owned coverage and isolated PostgreSQL acceptance. Security remains terminal non-passing only at the central Dependency Review availability probe tracked by .github#810; CodeQL remains terminal non-passing only after current-head dispatch succeeds and the central verdict handoff fails, tracked by .github#1927/#1929. These foreign control-plane failures are not leaf source defects and do not authorize no-op churn, synthetic verdicts, gate weakening, or mutable-source adoption. A qualifying independent approval is still absent.

Dependency-first Draft #248 / Issue #247 contains the next forward-only owner-table adoption, least-privilege runtime role and schema-qualified PostgreSQL read adapter. #250 adds the durable dependency-ownership invariant that a validated connection factory must be structurally bound against retained-reference replacement. #251 adds the migration-integrity invariant exposed by the owner-schema move: preserving a table OID, FKs, RLS and triggers is insufficient when an existing trigger/function body embeds a schema-qualified reference to the old relation. A forward owner migration must repair that dependent executable SQL in place while preserving function signature/trigger attachment and governance semantics; it must not paper over the defect with a compatibility copy/view or rewrite protected global migration history. #252 completes the adapter-side checked-versus-used rule: storing an executable connection capability immutably is insufficient if the read path later resolves a subclass-overridable property; execution must consume the exact structurally stored capability rather than perform a fresh dynamic lookup. #248 remains exact d54d44d795444df572efbb301a667d74ac574d58 on stale mutable-parent snapshot 656a0c41c06bc517b2cf7c554e35a6fb4f8c4f4b; it must not absorb mutable #235 source merely to restore mechanical mergeability. #235 integrates normally first; then #248 non-force adopts protected owner truth—including #249/#253/#254/#255—and reacquires exact-head coverage, PostgreSQL, security and review evidence before integration.

The durable follow-on after #248 integration is idempotent registration → explicit predictor/sample/decision-policy/analysis-protocol model → versioned scientific adapters/API/performance evidence. This independent lane does not change the People/Assignment owner order and must not copy mutable #63/#64/#65 source.

#63 exact Foundation CI is terminal success after its predecessor real RED (218 tests passed, 99.43% coverage) and three-branch test repair; SAST and Security are also terminal success. CodeQL remains failed in the central exact-head handoff state and qualifying approval is still absent, so normal integration remains blocked without an Orgmetra no-op retrigger or gate bypass. #64 owns #229#233 plus #246's replay-result reconciliation; its current exact head is 4be7f1681959e43d32c8e85a8f2660da36ff6d9c. Foundation, Security and SAST are terminal GREEN on that head; People API is 239/239 with 1472 statements / 482 branches at 100.00% statement/branch coverage and isolated PostgreSQL acceptance. CodeQL remains terminal FAILURE only at the same shared current-head verdict handoff after both compatibility jobs successfully request dispatch; no qualifying independent approval exists. #65 owns validate_authorization_decision(...) and purpose-bound durable-consumer validation. They overlap on People files, so #65 must non-force adopt protected #64 after normal #64 integration and preserve both invariant sets.

A further owner relationship is explicit: #141 contains a valid employing-legal-Organization HRIS feature but is Draft/non-mergeable on an old base and overlaps #64/#65 on People, authorization, and OpenAPI files. It must follow #65, non-force adopting protected owner truth while preserving its legal-employer feature. Assignment #163/#165 remain downstream consumers and must not adopt mutable sibling source.

Canonical People/Assignment durable order is #63#64#65#141#163#165, each through normal protected integration and non-force protected adoption where required. The independent workforce_validation order is #235#248 → later scientific/API increments, with mutable-parent source never treated as protected dependency evidence.

Writer branch repair finding

PR #100 remains Draft and non-mergeable because its long-lived branch is based on predecessor protected develop@ef1b143368cb6249c9520ca8cae10ebe844a5aa1. This is a repair finding, not a close condition. Its valid baseline delta is preserved; no force-push/destructive rebase is allowed. Safe non-force adoption of current protected truth must preserve valid doctoring while resolving real conflicts and reacquiring exact-head checks/review.

No self-approval, routine administrator bypass, gate weakening, predecessor-evidence substitution, mutable-owner source copy, or release claim is authorized by this PR.

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6266320a-d62c-4576-9ff6-4ac7ecbbcc6a

📥 Commits

Reviewing files that changed from the base of the PR and between c3289c8 and 4a07d0d.

📒 Files selected for processing (1)
  • docs/product-technical-gap-baseline.md

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

제품·기술 격차 기준 문서를 2026-08-26 기준으로 갱신했다. 조직 ruleset, control anchor, 활성 capability, 구매자 격차, 실행 검증 조건과 운영 진단을 최신 상태로 변경했다.

Changes

제품·기술 격차 기준

Layer / File(s) Summary
저장소 보호 및 실행 기준
docs/product-technical-gap-baseline.md
조직 ruleset 18156473과 PR #119 control anchor를 기록했다. Issue #89의 상업 통제 격차를 3건으로 확장했다. 실행 루프가 유효 ruleset과 현재 PR 그래프를 재조회하도록 갱신했다.
기능 상태 및 주요 격차
docs/product-technical-gap-baseline.md
PR #116–#119의 활성 capability를 추가했다. 목적 바운드 HR 반출, 권위적 성과목표, 접근성, 권위적 릴리스 운영을 최고 가치 구매자 격차로 정의했다.
운영 진단 및 참고문헌
docs/product-technical-gap-baseline.md
리뷰 트리아지와 제공자 복구 진행을 2026-08-25/26 기준 네 가지 항목으로 재작성했다. References (APA 7th) 제목과 목록은 유지했다.

Estimated code review effort: 2 (간단) | ~10분

Merge Risk: 🟡 Moderate · up to 4a07d

The baseline still contains an inaccurate section heading, a conflicting open-PR count, and unclear workflow rerun instructions. These can mislead readers about repository status and recovery steps, so the PR needs follow-up before merge.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 제품·기술 격차 기준 문서를 갱신하는 PR의 주요 변경 사항을 정확하고 간결하게 설명합니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/product-technical-gap-baseline

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Note

This report is out of date. Scroll down for Devin Review's latest report on this PR.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@seonghobae
seonghobae marked this pull request as draft August 23, 2026 15:03
@seonghobae
seonghobae marked this pull request as ready for review August 23, 2026 15:35
@seonghobae

Copy link
Copy Markdown
Contributor Author

@opencode-agent Please review the current unchanged head against protected develop. Local exact-head verification: all owned package suites pass at 100% statement/branch coverage.

@seonghobae
seonghobae marked this pull request as draft August 24, 2026 20:04
@seonghobae
seonghobae marked this pull request as ready for review August 24, 2026 20:07
coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@seonghobae
seonghobae marked this pull request as draft August 25, 2026 08:07
@seonghobae
seonghobae marked this pull request as ready for review August 25, 2026 10:26
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@seonghobae
seonghobae marked this pull request as draft August 25, 2026 20:55

Copy link
Copy Markdown
Contributor Author

Canonical baseline handoff from #292/#294, without competing write to docs/product-technical-gap-baseline.md: preserve the durable principle that high-impact Talent automation is governed at material decision-stage granularity, not only by a final decision label. A stage that materially constrains eligibility, inclusion/exclusion, shortlist/slate, ranking, suppression, thresholding, or routing must retain immutable ordered provenance (actual production mode, model/tool/version, exact evidence/policy versions, input/output/effect lineage, actor/disposition). Later human confirmation cannot erase or relabel upstream automated material effects. Effective human oversight requires pre-lock-in visibility of relevant evidence/limitations, a genuinely operable disregard/override/reverse/restore path and affected-option recoverability, plus controlled human disposition and purpose-bound reason/provenance. Irreversible/hidden automated exclusion or suppression fails closed. fully_automated_decision final high-impact Talent outcome remains non-authorizing provenance-only. Keep volatile PR/run IDs out of the baseline body; reconcile this invariant through #100's canonical single-writer path against then-protected truth.

Copy link
Copy Markdown
Contributor Author

talent_management baseline에 승계할 durable invariant가 하나 더 생겼습니다. Versioned legal/compliance/applicability policy는 high-impact Talent decision의 effective-human-oversight control을 면제할 수 없습니다. Automated material stage가 affected worker/option을 accountable reviewer에게 숨기거나, finalization 전에 effect를 비가역적으로 만들거나, 실제 사용 가능한 pre-lock-in restore/reversal path를 제거하면 finalization은 fail closed해야 합니다. Policy는 applicability와 required evidence를 정할 수 있지만 hidden/irreversible effect를 승인하거나 upstream automation을 human-supervised provenance로 세탁하는 권한은 갖지 않습니다. Source of truth는 Proposed ADR 0292이며, docs/product-technical-gap-baseline.md에는 #100 single-writer가 current protected truth와 reconcile한 뒤 volatile PR/run ID 없이 이 invariant만 반영해 주세요.

Copy link
Copy Markdown
Contributor Author

Durable baseline handoff from Keyverse binding owner #295 / Issue #297: raw issuer/subject syntax must never be represented as persistence-authorizing identity truth. Until Keyverse publishes an immutable released/versioned subject-assertion trust contract, Orgmetra may retain only explicitly non-authorizing validated candidate data and the durable-bind authority transition must fail closed. Future positive binding must consume the owner-published verification receipt/provenance through an ACL; no caller-controlled trusted flag, locally constructible fake receipt, token/JWKS verifier copy, cross-service SQL, or mutable Keyverse branch dependency. Keep this as a stable product/security invariant rather than embedding volatile PR/run IDs in docs/product-technical-gap-baseline.md.

Copy link
Copy Markdown
Contributor Author

Durable baseline handoff from Keyverse identity-binding work (#295/#297): preserve this as contract-level truth without volatile head/run identifiers.

A caller-supplied issuer/subject pair is syntax/identity candidate data only; it is not authentication or persistence authority. Orgmetra may create a durable positive identity binding only from immutable released/versioned Keyverse owner evidence whose contract/version and verification receipt/provenance are bound through an Orgmetra ACL. Until such owner evidence exists, the durable-binding path must fail closed. A caller-controlled trust flag, locally copied token/JWKS/signature verifier, mutable Keyverse branch dependency, source copy, or cross-service SQL is not an acceptable substitute.

The binding boundary must retain the existing runtime-integrity invariants: exact operational UUID/canonical-text validation, credential rejection, Nil/Max/forged-runtime rejection, and caller-alias detachment before retained identity use. Purpose-bound authorization remains a separate single-writer concern under #65; do not merge its runtime truth into the binding ACL baseline. This is a durable buyer/security dependency and should remain open conceptually until an immutable Keyverse owner release exists and the consumer positive path is implemented and verified.

Copy link
Copy Markdown
Contributor Author

Durable baseline handoff from canonical Keyverse binding owner #295: optional identity extra_claims are not trusted runtime capabilities. Before credential-name screening, the boundary must accept only None or an exact built-in dict and exact built-in string claim names, then compare only those inert names; it must not invoke caller-defined container truthiness/iteration or str.lower() behavior and must return bounded validation errors for malformed names. Claim values are not interpreted or retained. This is the same checked-before-used trust-boundary family already represented in the baseline, not a new aggregate. Keep volatile #295 SHAs/run IDs out of docs/product-technical-gap-baseline.md.

Copy link
Copy Markdown
Contributor Author

Durable baseline handoff from canonical Keyverse binding writer #295; no direct docs/product-technical-gap-baseline.md edit from that lane.

Extend the existing inert-input / credential-separation invariant with one narrow rule: metadata field names used for security classification must themselves be exact canonical inert text before classification. Exact built-in string type alone is insufficient if surrounding whitespace or blank names can evade the intended forbidden-name vocabulary. Classification should reject non-canonical/blank names rather than normalize attacker-controlled metadata into acceptance.

Exact evidence stays volatile here rather than in the baseline body: test-first #295 head b63c50a88f50dbeb1ea1a23eb58e781692f8427a produced real Foundation RED 34530360487/103049319749 (both padded Access_Token and blank claim-name regressions failed on the predecessor while 100% owned keyverse-adapter production coverage remained intact); minimal source successor is 694585a64d038d30e851e156b8d5423e567c14f8, which validates each claim name with the existing canonical-text boundary before credential screening. Keep authentication authority with released Keyverse evidence and authorization ownership with #65.

Copy link
Copy Markdown
Contributor Author

Durable baseline invariant handoff from canonical Keyverse binding lane #295; please integrate only if not already represented, without copying volatile run IDs.

For identity-adapter ingress, 'do not store raw credentials' starts before persistence: credential-shaped fields must not be accepted as ordinary identity metadata merely because the adapter ignores their values. Raw password/passkey/private-key material, OAuth/OIDC access/refresh/ID tokens, client secrets, and API keys should fail at the narrow input boundary before trust classification. The consumer must not parse or verify these values locally; Keyverse remains authentication authority and Orgmetra consumes only released/versioned trust evidence through an ACL.

Keep the principle separate from #295's current implementation SHA and from #65 purpose-bound authorization ownership.

Copy link
Copy Markdown
Contributor Author

Durable baseline handoff from the Keyverse binding ACL owner; please adopt in the canonical docs/product-technical-gap-baseline.md writer when reconciling:

A value advertised as validated across an identity boundary must not remain rewritable after validation merely because language-level frozen syntax can be bypassed with low-level attribute replacement. Detach caller-owned scalars/objects and use structurally immutable retained representation where the value is reused. This is data-integrity hardening, not authentication provenance: a locally constructible language object must never become trust authority by type/immutability alone, and every consequential consumer must reconstruct or revalidate the exact released owner evidence at its own boundary.

Current specimen: Orgmetra #295 test-first 634daefaad125b6de49bac4e0905dec1f822ccf3 → source successor 086fe88607b1e30f72633b5222fbcaf8f846e9ca. Keep volatile commit/run IDs out of the durable baseline text.

Copy link
Copy Markdown
Contributor Author

Durable baseline handoff from #295 current binding repair: an immutable outer candidate is not sufficient when it retains mutable UUID objects and returns those aliases. Cross-boundary operational identity should retain the already validated exact integer UUID scalar and expose fresh UUID(int=...) views, so caller mutation of a returned view cannot alter retained authority-bearing identity. This is an integrity invariant only; structural immutability or fresh views must not be treated as authentication provenance. #295 implements this at exact c7d39a6702ed2149c79dc2aa7c2c4be983679f9c and is Draft pending exact-head verification. Please fold the durable invariant into the canonical baseline only if not already covered by the existing nested-identity rule; avoid volatile SHA/run metadata in the baseline body.

Copy link
Copy Markdown
Contributor Author

Durable baseline invariant handoff from #300: workflow security validation must preserve YAML structural scope. A workflow-level permission default cannot be inferred from an indented/job-level permissions: block after whitespace normalization. Validation must distinguish top-level authority from narrower nested authority before accepting least privilege; comment/scalar normalization must not erase the indentation needed for that decision.

Reality evidence: test-only #300@b510e5eabb1142ebc1d4f612387bedfdb96161cc produced hosted Foundation RED 34561125160/103143892062 because the predecessor parser returned {'contents': 'read'} for jobs -> test -> permissions -> contents: read despite no workflow-level permissions. Ordinary successor 597a10b4a2d4a4b8139faf5a4240c40428896304 requires an unindented workflow-level permissions: key before reading scopes. Keep volatile SHAs/run IDs in #300/#301 metadata; reconcile only the durable structural-scope invariant into docs/product-technical-gap-baseline.md through this canonical writer.

Copy link
Copy Markdown
Contributor Author

Additional durable workflow-supply-chain invariants from #300 current repair: immutable-image validation must cover semantically equivalent GitHub Actions image syntax, including scalar job container: as well as object/service image:; and privileged-trigger validation must cover mapping, scalar shorthand, and flow-sequence on forms rather than one textual spelling. Equivalent YAML syntax must not create a policy bypass. This complements the previously handed-off structural-scope invariant for workflow/job permissions:. Keep exact head/run identifiers in #300/#301 metadata; reconcile only these durable syntax-equivalence/fail-closed rules through the canonical baseline writer.

Copy link
Copy Markdown
Contributor Author

Durable control-plane invariant handoff from active #300/#301: repository-owned workflow security validation must classify YAML mapping keys by parsed semantic key, not by one textual spelling. Bare, single-quoted and double-quoted equivalents of security-relevant keys (uses, image, container, permissions and permission scopes, on and privileged event names) must receive the same fail-closed treatment; list-form compact mappings such as - "uses": ... are included. A regex contract that only recognizes bare keys creates a parser differential where GitHub/YAML can interpret a control that the validator never inventories. Keep this as durable baseline truth once the canonical #300 writer repairs and protected integration proves it; do not freeze #300's volatile head/run identifiers into the baseline.

Copy link
Copy Markdown
Contributor Author

이번 cycle의 두 leaf repair에서 baseline에 남길 durable invariant만 handoff합니다. Leaf exact SHAs/run IDs는 이 comment evidence에만 두고 baseline 본문에는 휘발 상태로 고정하지 않는 것이 맞습니다.

  1. GitHub Actions executable dependency immutability: uses:docker://...는 local ./... action과 같은 예외가 아니라 원격 실행 dependency입니다. Repository/reusable-workflow ref는 full commit SHA, Docker action은 authoritative sha256 digest로 pin해야 하며 mutable tag/branch/ref와 unresolved expression은 fail closed해야 합니다. Bare/quoted/list-form 등 YAML 표현 차이가 security classification을 바꾸면 안 됩니다. Orgmetra#300 current ordinary-forward repair a50e591d6b3fd690e830399b7920c383aaa6975e가 이 invariant를 executable regression으로 구현했습니다.

  2. PostgreSQL RLS write-scope evidence: cross-tenant SELECT가 0 rows라는 behavioral proof만으로 WITH CHECK write isolation을 입증할 수 없습니다. Consequential tenant-owned tables는 ENABLE+FORCE RLS, permissive-policy cardinality, polcmd, exact normalized USING/WITH CHECK semantics를 catalog에서 검증하고, 실제 INSERT privilege를 가진 probe role이 constraint-valid cross-tenant write를 시도해 RLS 자체로 거부되는 것을 함께 증명해야 합니다. Orgmetra#304 current ordinary-forward repair 68306194f88b5a6beaf4fa06f8c340135572a180이 child job-analysis tables에 이 contract를 적용했습니다.

두 항목 모두 domain ownership을 옮기지 않습니다. #300은 repository supply-chain contract이고 #304는 job_architecture persistence evidence hardening입니다. Canonical baseline single-writer는 #100을 유지합니다.

Copy link
Copy Markdown
Contributor Author

#304에서 RLS acceptance의 추가 durable invariant가 확인됐습니다. Predicate shape와 negative cross-tenant probe만으로는 policy applicability를 증명하지 못합니다. RLS가 켜져 있어도 정책이 probe/runtime role에 적용되지 않으면 PostgreSQL default-deny 때문에 SELECT=0/INSERT rejection이 false-green이 될 수 있습니다. 현재 #304 successor f2f3585395239868f34e2cc28197442873974286은 child policy의 polroles = ARRAY[0::oid](PUBLIC), polcmd='*', exact normalized USING/WITH CHECK를 함께 고정하고 probe role을 명시적 NOBYPASSRLS least-privilege role로 만든 뒤 behavioral SELECT/INSERT rejection을 유지합니다. Baseline에는 volatile SHA가 아니라 다음 원칙만 반영해 주세요: RLS evidence는 ENABLE/FORCE + policy cardinality/command/predicate뿐 아니라 intended role applicability까지 catalog에서 증명하고, explicit non-bypass runtime/probe role의 real read/write behavior와 함께 검증해야 한다. Default-deny 자체를 tenant-isolation proof로 오인하면 안 된다. #100 single-writer를 존중해 이 branch에서는 baseline 파일을 수정하지 않습니다.

Copy link
Copy Markdown
Contributor Author

Durable packaging-contract refinement from fresh Job Analysis review (#305): source-tree PYTHONPATH tests can hide two distinct metadata failures, and the baseline should keep them separate from runtime/product semantics.

  1. A service distribution's declared Python floor must be at least the maximum lower bound required by every mandatory owned distribution it pins. Importing owned src directories directly is not installation evidence.
  2. If a service contract claims that every internal orgmetra-* dependency is canonical, validation must compare the declared internal dependency set with the canonical owned name==version set, not merely assert expected <= declared. The subset form admits an extra stale/unknown internal pin and produces a false green.
  3. Real installability of the built/distribution closure remains a separate acceptance tier; metadata equality/floor checks do not by themselves prove wheel/sdist resolver installation.

#305 now owns the Job Analysis implementation/test repair ordinary-forward. #64 owns the analogous People contract and received a non-competing handoff. Please fold only this durable invariant into docs/product-technical-gap-baseline.md when #100 next reconciles; do not record volatile #305 SHAs/run IDs in the baseline body.

Copy link
Copy Markdown
Contributor Author

Follow-up to 5631413308: internal-distribution ownership must be classified on the normalized project name, not a literal orgmetra- prefix. PyPA's current canonical rule lowercases names and collapses runs of ., _, and - to -: https://packaging.python.org/en/latest/specifications/name-normalization/

Durable invariant: normalize for namespace/ownership classification, but require the declared internal requirement itself to match the canonical exact owned name==version contract. Otherwise underscore/dot aliases can either evade the internal set as apparent third-party dependencies or become accidental alternate canonical spellings. #305 owns the Job Analysis executable repair; #64 owns the analogous People repair.

Copy link
Copy Markdown
Contributor Author

Durable product/control gap from #303 for the canonical baseline: candidate-document disposition and worker statutory-record retention must remain separate bounded-context responsibilities rather than one generic “HR data retention” timer.

Protected architecture already gives document_records canonical document/image artifact retention/export/delete ownership. The durable Context Map should therefore record:

  • talent_acquisition owns candidate/application/requisition truth, hiring-decision finalization, return-request/disposition semantics, talent-pool purpose/lawful-basis enrollment and candidate→worker transition classification;
  • people_core owns Worker/Employment truth, statutory employee-record categories and authoritative employment events that anchor later retention calculations;
  • document_records owns raw artifact retention/return/export/delete execution and deletion receipts through released contracts; no raw candidate-document copy or cross-service SQL;
  • physical-return applicability, privacy retention/deletion, talent-pool secondary purpose, employee statutory retention and legal hold are distinct policy dimensions with jurisdiction/effective-date/versioned evidence;
  • confirmed hire does not reclassify an entire resume/evidence set into an employee record; only purpose-justified minimal records transition;
  • immutable audit cannot become an indefinite raw-PII retention backdoor, and deletion acceptance must account for search/cache/export/backup recovery paths.

Current Korean primary-law anchors and detailed acceptance scenarios are now maintained on #303; keep volatile statutory dates/URLs in TRACEABILITY/doctoring rather than duplicating them into the durable baseline unless the baseline needs the governing invariant. Do not edit #303 implementation from this baseline lane.

Copy link
Copy Markdown
Contributor Author

Durable baseline handoff from #303/#306/#307. New candidate-document lifecycle boundary should enter docs/product-technical-gap-baseline.md only through this canonical writer: talent_acquisition owns candidate/recruiting disposition intent and hiring-decision anchor; people_core owns confirmed-hire/statutory worker truth; document_records alone executes artifact hold/return/export/delete and receipts through released ACLs. Return eligibility is separate from PIPA retention/deletion, talent-pool purpose is separate and expiring/revocable, confirmed hire is minimum field/document materialization rather than whole-application reclassification, and legal hold blocks every destruction state. Implementation #307 is now dependency-first Draft on Proposed ADR #306 and must also wait for canonical Foundation package discovery #258/#259. Current packet hardening adds claim-window ordering and structural post-validation immutability; volatile SHAs/check IDs belong in PR metadata rather than baseline body.

Copy link
Copy Markdown
Contributor Author

Additional durable runtime-integrity invariant from #307: an evidence packet is not structurally/content immutable merely because its outer object is tuple-backed. Retained built-in containers can still embed caller-owned behavior; here an exact datetime retained a mutable/custom tzinfo, so caller mutation changed later canonical JSON/SHA-256 without replacing the packet. Canonical evidence constructors should validate then detach retained time values into inert built-in UTC datetimes/scalars before storage, and exact boolean evidence must reject int-like truthy values. #307 test-first b5b1e618... -> repair f42bfcef... is the volatile implementation evidence; baseline should keep the invariant, not these SHAs.

Copy link
Copy Markdown
Contributor Author

#307 CandidateDocumentDisposition에서 재현된 durable runtime-evidence invariant를 baseline single-writer에 handoff합니다. 현재 child source audit에서 두 checked-versus-used 결함을 ordinary-forward로 수리했습니다. (1) trust-bearing identifier/reference/code/digest/governed-constant text가 isinstance(..., str) 또는 값 비교만 통과하면 caller-defined str subtype이 canonical packet에 retained될 수 있으므로, consequential evidence boundary는 비교·정규식·UUID parse·retention 전에 exact built-in str를 요구해야 합니다. Test-first f589d1ef910b4477837863c5f20dfefb3a1b30f5 → repair 76f7b60146d9e8a380ac8bc1fe11f9af08264110. (2) exact outer datetime만으로는 nested tzinfo가 inert하다는 뜻이 아니며, value.utcoffset()/astimezone() 전에 caller-defined timezone callback이 실행될 수 있습니다. Transport/evidence timestamp가 executable timezone semantics를 필요로 하지 않는 경계에서는 nested timezone authority를 먼저 built-in datetime.timezone으로 제한한 뒤 UTC로 detach해야 합니다. Test-first d41523b6b446089b9dbd94e3fcf328aa607faefc → repair 15d6dcacbaa6677bd9c87e7e9fb5d77b4b73d3e5. 이는 Python same-process sandbox claim이 아니라 retained/executed evidence shape를 inert primitive로 제한하는 규칙입니다. #100만 docs/product-technical-gap-baseline.md를 수정하고, 이 child는 baseline 파일에 경쟁 write하지 않습니다.

Copy link
Copy Markdown
Contributor Author

#307에서 ADR 0303/Issue #303의 반환 lifecycle을 코드와 다시 대조해 추가 durable invariant를 수리했습니다. 단순 enum state는 완료 증거가 아닙니다. return_dispatched 이후 상태는 authoritative dispatch timestamp를 가져야 하고 그 시각은 hiring_decision_finalized_at 이후여야 합니다 (16008120... RED → 70ef86a1... repair). 더 나아가 ADR이 요구하는 request/verify/dispatch/deliver/destroy 흐름과 Issue #303의 “반환/전달 완료 전 파기 금지”를 구현하기 위해 return_delivered state와 return_delivered_at evidence를 추가하고, delivery가 dispatch보다 앞설 수 없으며 return_destroyed는 delivery receipt 없이는 구성될 수 없게 했습니다 (61bf81af... RED → 4c1322b0... repair, fixture/current-contract follow-up 45128373..., b1a2d15e...). Baseline에는 consequential lifecycle state가 이름만으로 완료를 주장하지 않고 predecessor event receipt/timestamp를 함께 요구한다는 원칙을 반영해 주세요. #100 single-writer는 계속 유지하며 child에서 baseline 파일을 직접 수정하지 않습니다.

Copy link
Copy Markdown
Contributor Author

Durable lifecycle-evidence invariant from fresh #307 audit (2e2c42678f565dfd2e6307f154f51d8f22bd7f36): stateful evidence packets must enforce both directions of the causal contract. Requiring predecessor evidence for a later state is insufficient if an earlier authoritative state may still retain future-stage receipts/timestamps. A packet such as state=created with verified-request/SLA/dispatch/delivery evidence is internally contradictory even when each timestamp is locally valid. Canonical acceptance should define a state→allowed-evidence envelope: later states retain required predecessor evidence, while earlier states reject evidence that semantically belongs only to future states. This applies beyond candidate documents to immutable command/result/audit packets generally.

Do not encode this as “reject every late real-world event”: SLA breaches and other non-compliant events must remain representable as reality and carry explicit compliance outcome/evidence. The invariant is about preventing authoritative lifecycle state from lagging its own claimed completed-event evidence. Keep volatile #307 SHA/test lineage in PR metadata rather than the baseline body.

seonghobae commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

#307 current-head durable invariant handoff — 3af683009667f0c54f71c3e7ecc5dc6c83f9aaf3.

Immutable lifecycle/audit packets need bidirectional causal evidence. It is not enough for later states to require predecessor receipts; an earlier authoritative state must also reject receipts that claim a later stage has already completed. #307 now test-first covers created/return_claim_window_open -> request, return_requested -> verification/SLA, return_request_verified -> dispatch, and return_dispatched -> delivery, then minimally rejects those future-stage combinations while preserving late real-world events as factual evidence. Deadline misses should be represented as separate compliance outcomes, not erased by timestamp validation.

State names that encode a control condition must also agree with the control evidence itself. #307 found legal_hold_suspended + legal_hold=False was constructible; test-first 887ab342... and successor 2fd12e5f... now require an active hold when the authoritative state is legal_hold_suspended, while the existing destruction-state fail-closed rule remains intact.

A fixture-level invariant surfaced at the same time: whenever a new mandatory policy-computed receipt such as return_due_at or claim_window_end enters production validation, broad state matrices/canonical-serialization fixtures must advance in the same causal commit stack; otherwise tests can become stale while a stacked PR has no hosted Foundation execution.

Please incorporate these as code-current baseline invariants when the canonical docs/product-technical-gap-baseline.md lane next moves. This #307 lane does not edit that file directly.

Copy link
Copy Markdown
Contributor Author

#307 current exact b0add8173ef5303c76d37fbeb02fe6e47fafa985에서 statutory-retention evidence gap을 ordinary-forward로 닫았습니다. Predecessor 3af683...statutory_retainedstatutory_retention_expired_destroyed 모두 statutory_retain_until=None을 허용해, 무기한 보존과 근거 없는 expiry claim을 구분할 수 없었습니다. Test-first 0bb11541... → causal source fix 3c61995f... → broad fixture alignment b0add817... 순서로 두 상태에 policy-computed deadline evidence를 필수화했습니다. 기간 자체는 하드코딩하지 않습니다. Baseline durable invariant는 statutory retention을 주장하는 상태가 정책 경계 timestamp 없이 존재해서는 안 되며, retain/expiry 양쪽 모두 versioned policy evidence로 fail closed해야 한다입니다. #100의 docs/product-technical-gap-baseline.md single-writer ownership은 유지하며 이 lane에서 파일을 경쟁 수정하지 않습니다.

Copy link
Copy Markdown
Contributor Author

Durable lifecycle evidence invariant from #307 exact fdda3d8039e38904fa33dcc079d8b6e5d523fe43: state/evidence causality is bidirectional across the entire return envelope. Pre-request states (created, return_claim_window_open) must reject not only request receipt/timestamp but verification, policy SLA, dispatch, and delivery evidence; otherwise later-stage completion evidence can leak into an earlier authoritative state. Current repair is test-first d94b4e78... → causal source fdda3d8..., with current review threads resolved.

Second durable DDD/audit invariant: a consumer state named *_destroyed is not authoritative merely because prerequisite timestamps/policy deadlines are present. Destruction/return execution belongs to document_records; completed states require an immutable, tenant-scoped, released/versioned owner receipt plus recovery-aware deletion evidence. Canonical prerequisite is now #308. Leaf contexts must consume its opaque receipt/ACL by exact version, never copy a receipt schema or infer destruction from local timestamps. Please fold these into the code-current baseline when the #100 writer next updates docs/product-technical-gap-baseline.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation priority: medium status: draft type: docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant