Skip to content

Enforce vesting condition graph integrity#254

Draft
HardlyDifficult wants to merge 78 commits into
codex/ocf-stock-security-balancefrom
codex/ocf-vesting-graph-integrity
Draft

Enforce vesting condition graph integrity#254
HardlyDifficult wants to merge 78 commits into
codex/ocf-stock-security-balancefrom
codex/ocf-vesting-graph-integrity

Conversation

@HardlyDifficult

@HardlyDifficult HardlyDifficult commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stacked on #253.

This enforces OCF vesting-condition graph integrity inside VestingTerms validation. A vesting terms object now rejects final data where:

  • vesting condition IDs are duplicated
  • next_condition_ids contains duplicate IDs
  • next_condition_ids references a missing vesting condition
  • a condition is unreachable from the first vesting_conditions entry, which OCF treats as the graph root
  • more than one VESTING_START condition is present
  • VESTING_SCHEDULE_RELATIVE.relative_to_condition_id references a missing condition or itself
  • a relative trigger does not reference a predecessor condition on a next_condition_ids path
  • a relative trigger's anchor does not dominate every path from the graph root to the dependent condition
  • the condition graph contains a cycle, including cycles introduced by relative-trigger dependency edges

The check runs through validateOcfVestingTermsData, so it applies to both creates and edits.

OCF requirement references

Source checked against Open-Cap-Format-OCF at dd84bdb6bafb63681c77166f315cea5a2078a4c8.

Review feedback carried forward

  • Relative triggers must point to predecessor conditions, and the anchor must dominate every path to the dependent condition.
  • Orphaned vesting conditions are rejected by reachability from the first condition in the array.
  • Event-only or absolute roots are allowed when they are the first condition, matching the OCF explainer.
  • Duplicate checks and graph traversals use Set-based visited state to avoid repeated work on larger DAGs.

Stack/version

  • OpenCapTable-v34 package version: 0.0.13
  • Includes regenerated DAR and dars.lock entries for the stacked category branch.

Validation

Exact head: 1591822700805a917da2173f3e87c3d17c2a2c2b

  • npm run build
  • npm test (complete suite; 610 test scripts: 608 behavioral + 2 setup)
  • npm run lint (0 errors; 2 pre-existing warnings in scripts/remove-participant-dar.ts)
  • npm run lint:daml
  • npm run format
  • npm run check:schema-gaps -- --ocf-schema-dir /tmp/open-cap-format-ocf-schema-check/schema
  • npm run verify-dars
  • npm run verify-package
  • npm run check-upgrade-compat (0.0.12 -> 0.0.13)
  • git diff --check
  • OpenCapTable-v34-0.0.13.dar: SHA-256 4caa07fd6391427d8c83303f29f4f63b92a4edd7044c8489212442e9bf647c50, 3,192,596 bytes

Note

Medium Risk
Tightens on-ledger validation for cap-table vesting data; legitimate schedules that violate the new graph rules will fail create/edit, but logic is localized to VestingTerms with extensive tests.

Overview
Vesting terms now reject invalid OCF vesting-condition graphs at template ensure time via a new validateOcfVestingConditionGraph step wired into validateOcfVestingTermsData (creates and edits).

The checks cover unique condition IDs, unique next_condition_ids, known references, reachability from the first condition as graph root, at most one VESTING_START, relative-trigger predecessor and anchor-dominance rules, and acyclicity (including edges implied by relative_to_condition_id).

OpenCapTable-v34 is bumped to 0.0.13 with an updated test DAR dependency, regenerated packaged DAR/dars.lock, and broad Daml Script coverage for invalid graphs plus one edit-path regression.

Reviewed by Cursor Bugbot for commit 1591822. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features

    • Added comprehensive validation for vesting-condition graphs, including duplicate IDs, invalid references, unreachable conditions, incorrect relative anchors, and cycles.
    • Added support for validating vesting graphs during both creation and editing.
    • Updated the package to version 0.0.13.
  • Bug Fixes

    • Invalid vesting schedules are now rejected before they can be saved.
  • Tests

    • Added extensive coverage for invalid and valid vesting-condition graph scenarios.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds graph-level validation to Daml vesting terms, covering condition references, roots, reachability, relative-trigger dominance, and cycles. It also bumps the package to 0.0.13, updates the Test DAR dependency, refreshes DAR metadata, and adds create/edit validation tests.

Changes

Vesting condition graph validation

Layer / File(s) Summary
Graph validation logic and integration
OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml
Adds graph-validation imports, integrates graph validation into vesting-terms validation, and implements reference, reachability, anchor-dominance, edge, and cycle checks.
Test helpers and graph-validity scenarios
Test/daml/OpenCapTable/TestVestingTerms.daml
Adds reusable constructors and submission wrappers, with negative cases for invalid graphs, a positive event-only root case, and an edit that introduces invalid references.
Package version bump and DAR reference
OpenCapTable-v34/daml.yaml, Test/daml.yaml, dars/OpenCapTable-v34/0.0.13/OpenCapTable-v34.dar
Updates the package version, Test project dependency, and DAR LFS pointer metadata to 0.0.13.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TestVestingTerms
  participant CT.UpdateCapTable
  participant validateOcfVestingTermsData
  participant validateOcfVestingConditionGraph

  TestVestingTerms->>CT.UpdateCapTable: submit vesting terms create or edit
  CT.UpdateCapTable->>validateOcfVestingTermsData: validate vesting_conditions
  validateOcfVestingTermsData->>validateOcfVestingConditionGraph: validate condition graph
  validateOcfVestingConditionGraph->>validateOcfVestingConditionGraph: check references, reachability, dominance, and cycles
  validateOcfVestingConditionGraph-->>validateOcfVestingTermsData: return graph validity
  validateOcfVestingTermsData-->>CT.UpdateCapTable: return overall validation result
  CT.UpdateCapTable-->>TestVestingTerms: succeed or fail
Loading
🚥 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.
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 The title clearly summarizes the main change: new validation enforcing vesting condition graph integrity.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/ocf-vesting-graph-integrity

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

@HardlyDifficult HardlyDifficult marked this pull request as ready for review July 9, 2026 04:01
@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@copilot review

Copilot AI commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@copilot review

Addressed in 2bd0754: cycle detection now includes relative_to_condition_id edges, and I added a regression test for relative-trigger cycles.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e6d657d24

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml Outdated
Comment thread OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml Outdated
Comment thread OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml Outdated
Comment thread OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml`:
- Around line 260-268: `vestingConditionHasCycle` currently only uses the
current path, so shared subgraphs are re-walked across branches and can explode
exponentially. Update the DFS in `VestingTerms.daml` to thread an additional
accumulated visited set alongside `path`, marking nodes that have already been
fully explored with no cycle. Use that visited set in the recursive
`vestingConditionHasCycle`/`conditionById` traversal so each
`OcfVestingCondition` is expanded at most once while still detecting back-edges
via the current path.
- Around line 254-268: The edge construction in vestingConditionEdgeIds is
reversed for OcfVestingScheduleRelativeTrigger.relative_to_condition_id, which
makes valid relative chains look cyclic. Update vestingConditionEdgeIds so the
referenced condition points to the current condition instead of appending
relative_to_condition_id to the current node’s outgoing edges, and keep
vestingConditionHasCycle using the corrected graph shape so
validateOcfVestingConditionGraph no longer flags normal schedules as cycles.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2de591c1-302a-4c30-b9a2-1920dae126e1

📥 Commits

Reviewing files that changed from the base of the PR and between 572b318 and 2bd0754.

⛔ Files ignored due to path filters (1)
  • dars/dars.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • OpenCapTable-v34/daml.yaml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml
  • Test/daml.yaml
  • Test/daml/OpenCapTable/TestVestingTerms.daml
  • dars/OpenCapTable-v34/0.0.7/OpenCapTable-v34.dar

Comment thread OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml Outdated
Comment thread OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml Outdated
@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@copilot review

Copilot AI commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@copilot review

Addressed in 316c6f9 (follow-up commits: a856cd6, 0d8b82f): relative-trigger edges now flow from relative_to_condition_id to the dependent condition for cycle detection, and the vesting fixture now covers a valid start -> c1 chain with c1.relative_to_condition_id = "start".

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@copilot review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: e960746a94

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@HardlyDifficult HardlyDifficult marked this pull request as draft July 11, 2026 06:42
@HardlyDifficult HardlyDifficult marked this pull request as ready for review July 11, 2026 08:32
@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@copilot review

Please review exact head 0ae9f4b31fdaf3ac2697513f2e23abdc7ce23bec, focusing on vesting-condition graph reachability, relative-trigger dominance, and cycle detection after the parent security-balance fixes. CI is green, the branch is merge-clean, all 605 test scripts pass locally, and the thread-aware sweep has no unresolved comments.

Copilot AI commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@copilot review

Please review exact head 0ae9f4b31fdaf3ac2697513f2e23abdc7ce23bec, focusing on vesting-condition graph reachability, relative-trigger dominance, and cycle detection after the parent...

Reviewed exact head 0ae9f4b31fdaf3ac2697513f2e23abdc7ce23bec with a focused pass on vesting-condition reachability/root semantics, relative-trigger dominance/predecessor constraints, and cycle detection (including relative dependency edges). I also re-checked Actions on both codex/ocf-stock-security-balance and codex/ocf-vesting-graph-integrity; latest CI and Check DAR Integrity runs are green for this SHA. I don’t see additional actionable changes needed in this PR.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@codex review exact head 0ae9f4b31fdaf3ac2697513f2e23abdc7ce23bec. Please focus on vesting graph root reachability, relative-trigger predecessor/dominance rules, and cycle detection.

@coderabbitai resume
@coderabbitai review exact head 0ae9f4b31fdaf3ac2697513f2e23abdc7ce23bec

Copilot completed this exact-head review with no findings; CI is green and all review threads are clear.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@cursor review Please review exact head 0ae9f4b31fdaf3ac2697513f2e23abdc7ce23bec, focusing on vesting graph reachability, relative-trigger dominance, and cycle detection after the parent restack. Copilot has completed this exact revision with no findings.

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 0ae9f4b. Configure here.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: 0ae9f4b31f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml`:
- Around line 232-235: The vestingGraphRootConditionId function must identify
the graph’s start condition from its structure rather than selecting
conditions[0]. Derive the root using the existing ID-linked relationships, such
as the node with no incoming edges or the start-trigger condition, while
preserving None for an empty or rootless graph and ensuring
allConditionsReachableFromStart validates unordered condition lists correctly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 42ba6793-0bcd-4343-b81d-737b16d05f16

📥 Commits

Reviewing files that changed from the base of the PR and between d8a08e6 and 0ae9f4b.

⛔ Files ignored due to path filters (1)
  • dars/dars.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • OpenCapTable-v34/daml.yaml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml
  • Test/daml.yaml
  • Test/daml/OpenCapTable/TestVestingTerms.daml
  • dars/OpenCapTable-v34/0.0.13/OpenCapTable-v34.dar

Comment thread OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/VestingTerms.daml
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

@HardlyDifficult I'll resume automatic reviews and run a fresh review on the current head (0ae9f4b31fdaf3ac2697513f2e23abdc7ce23bec), focusing on vesting graph root reachability, relative-trigger predecessor/dominance rules, and cycle detection.

✅ Action performed

Reviews resumed.


Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@HardlyDifficult HardlyDifficult marked this pull request as draft July 11, 2026 08:42
@HardlyDifficult HardlyDifficult marked this pull request as ready for review July 11, 2026 08:44
@HardlyDifficult HardlyDifficult self-assigned this Jul 11, 2026
@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

Restacked onto the final reviewed head of #253 (c271839b043ff31f55e56448644eccd4b9765e53).

Exact head: 1591822700805a917da2173f3e87c3d17c2a2c2b

Fresh validation on the combined branch:

  • full DAML suite: 610 scripts (608 behavioral + 2 setup)
  • focused vesting-graph suite: 21 scripts (19 behavioral + 2 setup)
  • build, codegen/package verification, formatting, ESLint (0 errors; 2 pre-existing warnings), DAML lint, and git diff --check
  • OCF schema parity: 55/55 object-type mappings clean
  • all 13 committed DARs verified
  • upgrade compatibility: 0.0.12 -> 0.0.13
  • 0.0.13 DAR: 24923ebd1e8699a23d1e5c23ac94ecfd8fd465655fbd13aaa593079a942d0334, 3,193,070 bytes

Keeping this PR in draft until exact-head CI is green.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

CI is green and all 16 review threads are resolved on exact head 1591822700805a917da2173f3e87c3d17c2a2c2b. @copilot review

Copilot AI commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

CI is green and all 16 review threads are resolved on exact head 1591822700805a917da2173f3e87c3d17c2a2c2b. @copilot review

Reviewed exact head 1591822700805a917da2173f3e87c3d17c2a2c2b with focused checks on vesting graph root reachability, relative-trigger predecessor/dominance, and cycle detection. I also verified Actions on both codex/ocf-stock-security-balance and codex/ocf-vesting-graph-integrity; CI and Check DAR Integrity are green for the current SHA. No additional code changes are needed in this PR.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@codex review exact head 1591822700805a917da2173f3e87c3d17c2a2c2b. Copilot completed this exact revision with no findings. Please focus on vesting graph root reachability, relative-trigger predecessor/dominance rules, and cycle detection after the parent restack.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@cursor review Please review exact head 1591822700805a917da2173f3e87c3d17c2a2c2b, focusing on vesting graph reachability, relative-trigger dominance, and cycle detection after the parent restack. Copilot completed this exact revision with no findings.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review exact head 1591822700805a917da2173f3e87c3d17c2a2c2b. Copilot completed this revision with no findings. Please perform the canonical exact-head review.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

@HardlyDifficult I'll perform a fresh review on exact head 1591822700805a917da2173f3e87c3d17c2a2c2b, focusing on the vesting-condition graph invariants (root/reachability, relative-trigger predecessor and dominance checks, cycle detection, and the single-VESTING_START constraint).

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cursor cursor 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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 1591822. Configure here.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 1591822700

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Collaborator Author

Preliminary OCF validation-policy audit

Policy: OCF Validation Policy

Appears supported

  • Vesting conditions form a documented directed/acyclic graph.
  • Condition IDs and next_condition_ids/relative-condition references must resolve consistently.
  • Schema-declared condition-ID and array uniqueness rules.

Needs line-by-line evidence or narrowing

  • Anchor-dominance, all-path reachability, predecessor-linkage, or root-shape requirements beyond the documented graph model.
  • Any rule that chooses one graph interpretation where OCF permits more than one.

Proposed next step
Keep the core graph/reference checks and discuss the additional reachability rules individually. No merge recommendation yet.

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.

3 participants