Skip to content

Enforce OCF schema field constraints - #269

Draft
HardlyDifficult wants to merge 207 commits into
mainfrom
codex/ocf-schema-constraints-category
Draft

Enforce OCF schema field constraints#269
HardlyDifficult wants to merge 207 commits into
mainfrom
codex/ocf-schema-constraints-category

Conversation

@HardlyDifficult

@HardlyDifficult HardlyDifficult commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Standalone OCF schema/field validation on main. This consolidates the field-format work previously split across #257 through #267, without carrying their former stacked parents.

The standalone scope enforces constraints directly representable in OpenCapTable-v34:

  • schema-declared array cardinality and uniqueness for transfer, consolidation, conversion, exercise, release, and reissuance fields
  • Document path / uri mutual exclusion
  • conversion-mechanism and trigger variant constraints
  • ISO currency, phone, and country-subdivision formats
  • stock issuance share-number range shape, quantity consistency, and within-issuance non-overlap
  • Monetary validation for optional stock cost_basis and warrant exercise_price

Cap-table-wide share-number lineage/overlap enforcement is intentionally excluded here because the old implementation depended on unmerged balance/ceiling engines. That behavior should be evaluated separately instead of importing predecessor validators into this field-constraint PR.

OCF basis

Primary sources include Document, StockIssuance, Monetary, CurrencyCode, Phone, CountrySubdivisionCode, and the conversion-right/mechanism schemas under schema/types.

Standalone state

  • Base: main
  • Exact head: 6a7b63ff5ec3b633a07204cf4a186d7b61d17592
  • Mutable DAR candidate: OpenCapTable-v34 0.0.3 only
  • Diff: 30 files; field validators, focused test modules/fixtures, and the single refreshed candidate DAR

Local validation

  • npm run build
  • npm run check:dar-version-policy -- --base origin/main
  • npm run verify-dars
  • git diff --check
  • npm test could not start locally because this Mac has no Java runtime; CI rerun and database replays remain pending.

Note

Medium Risk
Validation changes can reject previously accepted cap-table payloads (conversion rights, documents with both path and uri, duplicate security IDs, phone/currency/subdivision formats). Scope is contract ensure logic, not auth or payments.

Overview
Tightens OCF field validation across OpenCapTable-v34 ensure clauses so payloads must match schema-shaped rules before contracts are created.

Security ID arrays on transfers, consolidations, conversions, exercises, releases, and reissuances now use shared helpers for non-empty (where required) and unique elements; duplicate resulting_security_ids or consolidation security_ids are rejected.

Documents must have exactly one of path or uri (mutual exclusion), not both or neither. Conversion triggers delegate to validateOcfConversionTriggerFields so each trigger type only allows the optional fields OCF defines (dates, conditions, elective ranges).

Conversion mechanisms are stricter: convertible PPS/valuation/ratio variants are rejected as unsupported; stock-class conversion rights only accept the ratio mechanism with required conversion_price, ratio, and rounding_type and no extra optional fields; warrant valuation types must match CAP/FIXED/ACTUAL; share-price discounts when discount is false may still carry reference percent/amount.

Formats: ISO uppercase 3-letter currency codes, space-separated international phone patterns (with extensions), and 1–3 character country subdivision codes on issuer/address fields. Stock issuance share_numbers_issued must not overlap and must sum to quantity when present; optional cost_basis and warrant exercise_price get Monetary validation.

Adds focused DAML script tests and refreshes the OpenCapTable-v34 0.0.3 DAR artifact.

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

Summary by CodeRabbit

  • Bug Fixes
    • Strengthened validation for security identifiers, requiring non-empty, unique values where applicable.
    • Improved validation of conversion triggers, mechanisms, share ranges, currency codes, subdivision codes, and optional monetary fields.
    • Added structured phone-number validation, including international formats and extensions.
    • Documents now require exactly one of a path or URI.
  • Tests
    • Added coverage for phone numbers, currency codes, subdivision codes, conversion rules, share ranges, and duplicate identifiers.

HardlyDifficult and others added 30 commits July 8, 2026 18:35
…ing' into codex/ocf-reference-integrity

# Conflicts:
#	scripts/codegen/templates/CapTable.daml.template
#	scripts/codegen/templates/loops/edit-case.daml
…nto codex/ocf-stock-plan-pool-ceiling-v2

# Conflicts:
#	scripts/codegen/templates/CapTable.daml.template
…ing' into codex/ocf-reference-integrity

# Conflicts:
#	scripts/codegen/generate-captable.ts

@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: 6a7b63ff5e

ℹ️ 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/Types/Conversion.daml
Comment thread OpenCapTable-v34/daml/Fairmint/OpenCapTable/Types/Conversion.daml
@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

Addressed both exact-head Codex findings in c184a4e:

  • reject unsupported expires_at on stock-class conversion rights
  • carry rounding_type in an upgrade-compatible optional field and require it for the OCF ratio mechanism
  • added focused rejection tests and refreshed the candidate DAR/lock

Local validation: npm run build, npm run verify-dars, DAR version policy, and git diff --check pass. The full script test and upgrade checker require Java in this environment, so CI is the authoritative broad check.

@HardlyDifficult

HardlyDifficult commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@copilot review exact head c184a4e9738485f4930c4f5df5f5c0c1f26a6e4e.

@HardlyDifficult

HardlyDifficult commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review exact head c184a4e9738485f4930c4f5df5f5c0c1f26a6e4e.

@HardlyDifficult

HardlyDifficult commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@cursor review exact head c184a4e9738485f4930c4f5df5f5c0c1f26a6e4e.

Copilot AI commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@copilot review exact head c184a4e9738485f4930c4f5df5f5c0c1f26a6e4e.

Reviewed exact head c184a4e2142beac6f85b8bf31ed73f56e9ba9819. I don’t see any additional blocking issues to address.

@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 c184a4e. Configure here.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

Follow-up 3b74ab2d28464e70b132f8695108a817ae76efb4 appends the new optional field at the end of the DAML record, as required for package upgrade compatibility. Local build, DAR integrity/version policy, and diff checks pass. The stale-head replays were cancelled before their data phase and replaced with exact-head runs.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@copilot review exact head 3b74ab2d28464e70b132f8695108a817ae76efb4.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@codex review exact head 3b74ab2d28464e70b132f8695108a817ae76efb4.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@cursor review exact head 3b74ab2d28464e70b132f8695108a817ae76efb4.

Copilot AI commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@copilot review exact head 3b74ab2d28464e70b132f8695108a817ae76efb4.

Reviewed exact head 3b74ab2d28464e70b132f8695108a817ae76efb4. I don’t see any additional blocking issues to address.

@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 `@Test/daml/OpenCapTable/TestConversionMechanisms.daml`:
- Around line 153-158: Add positive test cases to the conversion-mechanism cases
around OcfConvMechPpsBased, covering discount-disabled PPS mechanisms with
exactly one of discount_percentage or discount_amount populated. Preserve the
existing invalid and supported cases, and ensure the tests verify both
schema-valid single-field forms.
🪄 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: dd5d222f-7ae4-4cd0-879d-569d742253ee

📥 Commits

Reviewing files that changed from the base of the PR and between ca1c6c9 and c184a4e.

⛔ Files ignored due to path filters (1)
  • dars/dars.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/ConvertibleConversion.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/EquityCompensationExercise.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/EquityCompensationRelease.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/StockConversion.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/StockIssuance.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/StockReissuance.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/WarrantExercise.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/WarrantIssuance.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/Types/Conversion.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/Types/Monetary.daml
  • OpenCapTable-v34/daml/Fairmint/OpenCapTable/Types/Stock.daml
  • Test/daml/OpenCapTable/TestConversionMechanisms.daml
  • Test/daml/OpenCapTable/TestCountrySubdivisionCode.daml
  • Test/daml/OpenCapTable/TestIssuer.daml
  • Test/daml/OpenCapTable/TestStockClass.daml
  • Test/daml/OpenCapTable/TestUniqueSecurityArrays.daml
  • dars/OpenCapTable-v34/0.0.3/OpenCapTable-v34.dar

Comment thread Test/daml/OpenCapTable/TestConversionMechanisms.daml

@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 3b74ab2. Configure here.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

Addressed the opportunistic positive-test gap in ba66040424067062afa0233c1b4239ad0eb0f894. This is test-only; the contract DAR is unchanged. Local full build passes. Exact-head replays were restarted before the data phase.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@copilot review exact head ba66040424067062afa0233c1b4239ad0eb0f894.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@codex review exact head ba66040424067062afa0233c1b4239ad0eb0f894.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

@cursor review exact head ba66040424067062afa0233c1b4239ad0eb0f894.

Copilot AI commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@copilot review exact head ba66040424067062afa0233c1b4239ad0eb0f894.

Reviewed exact head ba66040424067062afa0233c1b4239ad0eb0f894. I don’t see any additional blocking issues to address.

@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 ba66040. Configure here.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

SDK integration blocker discovered

The contract rule is correct, but current ocp-canton-sdk main does not preserve the official ratio mechanism losslessly:

  • normalization deletes nested rounding_type and silently drops a single 1:1 stock-class conversion right
  • the stock-class writer does not populate the new flattened DAML rounding_type
  • stock-class readback fabricates NORMAL and 0 USD instead of preserving actual rounding and conversion price
  • warrant stock-class rights have the same rounding omission

This means a replay can reject a valid non-1:1 right or appear green after silently deleting a valid 1:1 right. That violates the purpose of this validation framework, so this PR is not final-review ready even if the current snapshots pass.

Official basis: https://github.com/Open-Cap-Table-Coalition/Open-Cap-Format-OCF/blob/095182023cd620cc55d49777b5c8f75a3376120b/schema/types/conversion_mechanisms/RatioConversionMechanism.schema.json#L16-L30

Required dependency: lossless stock-class and warrant ratio round-trip support in ocp-canton-sdk, followed by exact-head dev/prod replay using that SDK.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: ba66040424

ℹ️ 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

Copy link
Copy Markdown
Collaborator Author

Read-only database impact confirmation

The SDK issue is exercised by current sync-enabled data, so it is not theoretical:

  • dev: 11 stock-class conversion rights across 10 portals; all are 1:1, including 3 FLOOR and 8 NORMAL
  • production: 8 rights across 6 portals; all are 1:1 NORMAL

Current SDK normalization deletes every one of these rights before contract submission because it treats a single 1:1 right as equivalent to no right. Therefore a green replay on the current SDK would be a false positive for these 19 objects, and the three dev FLOOR values are specifically not round-tripping.

Queries were read-only (REPEATABLE READ READ ONLY, rolled back); no data was changed.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

Narrow SDK dependency opened as draft: Fairmint/ocp-canton-sdk#447

It targets SDK main, preserves 1:1/non-1:1 rights, all rounding modes, and real conversion price, with 126 focused tests passing. It remains blocked until this PR’s generated daml-js binding is published and pinned, because every currently published encoder drops the new field.

@HardlyDifficult

Copy link
Copy Markdown
Collaborator Author

Final exact-head replay results (ba66040424067062afa0233c1b4239ad0eb0f894)

The new dev batch failure is consistent with the missing SDK rounding_type mapping introduced by this contract requirement. More importantly, these runs cannot prove full convergence because SDK 0.7.0 normalizes 19 current stock-class conversion rights away before contract submission/comparison.

Conclusion: keep draft; fix/publish the binding + SDK chain, then rerun both databases.

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