Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d510ecf
Enforce exact optional source boundaries
HardlyDifficult Jul 10, 2026
4ead58d
Merge branch 'codex/exact-public-config-state' into codex/exact-optio…
HardlyDifficult Jul 10, 2026
a9da845
Preserve command context parameter subtypes
HardlyDifficult Jul 10, 2026
73ca4dc
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 10, 2026
6e7e19f
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 10, 2026
928cd45
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 10, 2026
ffa81b4
Simplify required command context
HardlyDifficult Jul 10, 2026
0e915c9
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 10, 2026
3e72bbf
Keep command context return types sound
HardlyDifficult Jul 10, 2026
35c7f74
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 10, 2026
4a87f3d
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 10, 2026
efacdfd
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 10, 2026
4bc2097
Merge exact config updates into optional boundaries
HardlyDifficult Jul 11, 2026
64e0474
Merge nullable document fixes into exact optional boundaries
HardlyDifficult Jul 11, 2026
e6661a3
Merge commit '05705297c88e4ea3f3ac1d5b428717827372753e' into codex/ex…
HardlyDifficult Jul 11, 2026
d374476
Merge commit '7ecd4fc31735dd4677897122559ca9a90510583d' into codex/ex…
HardlyDifficult Jul 11, 2026
1b88a90
Merge commit '13907e62b70af6579f7098896ec8032defd10f11' into codex/ex…
HardlyDifficult Jul 11, 2026
0ed55f9
Merge prepared PR #417 into exact optional boundaries
HardlyDifficult Jul 11, 2026
0df1e02
Merge latest prepared PR #417 into exact optional boundaries
HardlyDifficult Jul 11, 2026
b49e489
Merge final public-config wrapper fix into exact optional boundaries
HardlyDifficult Jul 11, 2026
fedb046
Merge commit '8acc212b1ab78646a74278e4027b7d9af97b7031' into codex/ex…
HardlyDifficult Jul 11, 2026
a340f5a
Merge commit '7378dbfb06e56df15420ca5cef3b440b19424deb' into codex/ex…
HardlyDifficult Jul 11, 2026
bd5f391
Merge commit '16adf24dcbf258bcff1f983a689cbde249c414be' into codex/ex…
HardlyDifficult Jul 11, 2026
7d3a4ee
Merge commit 'fecee431e369a0c88dbc382ff4228484844b02cc' into codex/ex…
HardlyDifficult Jul 11, 2026
e5f5d28
Merge commit '88d2485c081a1bd2e78a9e27035d97c68271ac1d' into codex/ex…
HardlyDifficult Jul 11, 2026
7ca49b0
Merge commit '3755ffbb4877a6a14fd6618253d6d6d4b4439d89' into codex/ex…
HardlyDifficult Jul 11, 2026
1e1901f
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 11, 2026
8f30086
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 11, 2026
ac8df1f
Make applied command context typing sound
HardlyDifficult Jul 11, 2026
e7501f6
Materialize required command parameters
HardlyDifficult Jul 12, 2026
bd76820
Project command context inputs exactly
HardlyDifficult Jul 12, 2026
c339110
Merge hardened public config into exact optional boundaries
HardlyDifficult Jul 12, 2026
199d2b9
Merge commit '0971a4e74c2d7edf1150c913a2c3c165333096df' into codex/ex…
HardlyDifficult Jul 12, 2026
55833b3
Merge exact public config into optional boundaries
HardlyDifficult Jul 12, 2026
c1db98f
test: enforce exhaustive observability projections
HardlyDifficult Jul 12, 2026
ab6bb21
fix: keep exact boundary checks executable
HardlyDifficult Jul 12, 2026
f9bdc19
fix: harden applied command context snapshots
HardlyDifficult Jul 12, 2026
87e3086
docs: align submit carrier contracts
HardlyDifficult Jul 12, 2026
7fd6238
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 12, 2026
5131778
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 12, 2026
afb3b58
Merge remote-tracking branch 'origin/codex/exact-public-config-state'…
HardlyDifficult Jul 12, 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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@
"test:coverage": "jest --coverage --passWithNoTests",
"test:declarations": "ts-node --project tsconfig.tests.json scripts/check-declarations.ts && tsc -p tsconfig.declaration-tests.json --noEmit && npm run -s test:exact-public-config",
"test:exact-public-config": "tsc -p tsconfig.exact-public-config-tests.json --noEmit",
"test:exact-source": "tsc -p tsconfig.exact-source.json --noEmit",
"test:integration": "npm run -s typecheck && jest -c jest.integration.config.js --passWithNoTests",
"test:integration:ci": "npm run -s typecheck && jest -c jest.integration.config.js --runInBand",
"test:watch": "jest --watch",
"typecheck": "tsc -p tsconfig.tests.json --noEmit"
"typecheck": "tsc -p tsconfig.tests.json --noEmit && npm run -s test:exact-source"
},
"config": {
"localnet_quickstart_ref": "5c90cf4d0eb934712fd8c269b56e6272b605ccad"
Expand Down
9 changes: 4 additions & 5 deletions src/functions/OpenCapTable/capTable/CapTableBatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,9 +386,8 @@ export class CapTableBatch {
try {
const templateId = 'ExerciseCommand' in command ? command.ExerciseCommand.templateId : undefined;
const mergedContext = mergeCommandContext(this.params.defaultContext, this.params.context);
const context = mergeCommandContext(mergedContext, {
commandId: this.params.commandId ?? mergedContext?.commandId ?? createUpdateCapTableCommandId(),
});
const commandId = this.params.commandId ?? mergedContext?.commandId ?? createUpdateCapTableCommandId();
const context = { ...mergedContext, commandId };
response = await submitObservedTransactionTree(
this.client,
{
Expand All @@ -401,11 +400,11 @@ export class CapTableBatch {
...(this.params.logger === undefined ? {} : { logger: this.params.logger }),
...(this.params.metrics === undefined ? {} : { metrics: this.params.metrics }),
...(this.params.defaultContext === undefined ? {} : { defaultContext: this.params.defaultContext }),
...(context === undefined ? {} : { context }),
context,
},
{
operation: 'capTable.update',
templateId,
...(templateId !== undefined ? { templateId } : {}),
choice: 'UpdateCapTable',
}
);
Expand Down
10 changes: 8 additions & 2 deletions src/functions/OpenCapTable/capTable/archiveCapTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ function snapshotArchiveCapTableParams(
function buildArchiveCapTableCommandFromSnapshot(params: ArchiveCapTableParams): CommandWithDisclosedContracts {
return buildCapTableCommand({
capTableContractId: params.capTableContractId,
capTableContractDetails: params.capTableContractDetails,
...(params.capTableContractDetails === undefined
? {}
: { capTableContractDetails: params.capTableContractDetails }),
choice: 'ArchiveCapTable',
choiceArgument: {},
});
Expand Down Expand Up @@ -137,7 +139,11 @@ export async function archiveCapTable(
disclosedContracts,
},
observability,
{ operation: 'archiveCapTable', templateId, choice: 'ArchiveCapTable' }
{
operation: 'archiveCapTable',
...(templateId === undefined ? {} : { templateId }),
choice: 'ArchiveCapTable',
}
);

return { updateId: result.transactionTree.updateId };
Expand Down
2 changes: 1 addition & 1 deletion src/functions/OpenCapTable/capTable/getCapTableState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ async function buildCapTableStateFromCreatedEvent(
try {
const eventsResponse = await client.getEventsByContractId({
contractId: issuerContractId,
...ledgerReadScope({ readAs: issuerPartyId ? [issuerPartyId] : undefined }),
...ledgerReadScope(issuerPartyId ? { readAs: [issuerPartyId] } : {}),
});
const issuerId = requireIssuerCanonicalObjectId(eventsResponse, issuerContractId);
entities.set('issuer', new Set([issuerId]));
Expand Down
6 changes: 4 additions & 2 deletions src/functions/OpenCapTable/issuer/getIssuerAsOcf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ import { canonicalizeNumeric10 } from '../../../utils/numeric10';
import { damlAddressToNative, damlTimeToDateString, isRecord } from '../../../utils/typeConversions';
import { readSingleContract } from '../shared/singleContractRead';

function damlEmailToNative(damlEmail: Fairmint.OpenCapTable.Types.Contact.OcfEmail): OcfIssuerInput['email'] {
function damlEmailToNative(
damlEmail: Fairmint.OpenCapTable.Types.Contact.OcfEmail
): NonNullable<OcfIssuerInput['email']> {
return {
email_type: damlEmailTypeToNative(damlEmail.email_type),
email_address: damlEmail.email_address,
};
}

function damlPhoneToNative(phone: Fairmint.OpenCapTable.Types.Contact.OcfPhone): OcfIssuerInput['phone'] {
function damlPhoneToNative(phone: Fairmint.OpenCapTable.Types.Contact.OcfPhone): NonNullable<OcfIssuerInput['phone']> {
return {
phone_type: damlPhoneTypeToNative(phone.phone_type),
phone_number: phone.phone_number,
Expand Down
19 changes: 9 additions & 10 deletions src/functions/OpenCapTable/shared/singleContractRead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,32 +202,31 @@ export async function readSingleContract(
const templateIdentity = options.expectedTemplateId
? assertTemplateIdentity(
{
templateId,
packageName,
...(templateId !== undefined ? { templateId } : {}),
...(packageName !== undefined ? { packageName } : {}),
},
options.expectedTemplateId,
{
contractId: params.contractId,
operation: options.operation,
message:
templateId === undefined && packageName === undefined
? 'Contract template identity is missing; cannot validate expected template'
: undefined,
...(templateId === undefined && packageName === undefined
? { message: 'Contract template identity is missing; cannot validate expected template' }
: {}),
}
)
: undefined;

const createArgument = requireCreateArgumentRecord(createdEvent.createArgument, params.contractId, {
operation: options.operation,
templateId,
...(templateId !== undefined ? { templateId } : {}),
});

return {
contractId: params.contractId,
createArgument,
createdEvent,
templateId,
packageName,
templateIdentity,
...(templateId !== undefined ? { templateId } : {}),
...(packageName !== undefined ? { packageName } : {}),
...(templateIdentity !== undefined ? { templateIdentity } : {}),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,21 @@ function damlShareNumberRangeToNative(value: unknown, index: number): ShareNumbe
};
}

function damlStockIssuanceTypeToNative(t: string | null): StockIssuanceType | undefined {
if (t === null) return undefined;
function damlStockIssuanceTypeToNative(t: unknown): StockIssuanceType | undefined {
if (t === null || t === undefined) return undefined;
switch (t) {
case 'OcfStockIssuanceRSA':
return 'RSA';
case 'OcfStockIssuanceFounders':
return 'FOUNDERS_STOCK';
default:
throw new OcpParseError(`Unknown DAML stock issuance type: ${t}`, {
default: {
const detail = typeof t === 'string' ? `: ${t}` : '';
throw new OcpParseError(`Unknown DAML stock issuance type${detail}`, {
source: 'stockIssuance.issuance_type',
code: OcpErrorCodes.UNKNOWN_ENUM_VALUE,
context: { receivedValue: t },
});
}
}
}

Expand Down Expand Up @@ -171,6 +174,7 @@ export function damlStockIssuanceDataToNative(
};
})
: [];
const issuanceType = damlStockIssuanceTypeToNative(anyD.issuance_type);

const boardApprovalDate = optionalDamlTimeToDateString(d.board_approval_date, 'stockIssuance.board_approval_date');
const stockholderApprovalDate = optionalDamlTimeToDateString(
Expand Down Expand Up @@ -208,11 +212,7 @@ export function damlStockIssuanceDataToNative(
stock_legend_ids: Array.isArray((d as unknown as { stock_legend_ids?: unknown }).stock_legend_ids)
? (d as unknown as { stock_legend_ids: string[] }).stock_legend_ids
: [],
...((anyD as { issuance_type?: unknown }).issuance_type != null && {
issuance_type: damlStockIssuanceTypeToNative(
(anyD as { issuance_type?: unknown }).issuance_type as string | null
),
}),
...(issuanceType !== undefined ? { issuance_type: issuanceType } : {}),
comments:
(anyD as { comments?: unknown }).comments !== undefined &&
Array.isArray((anyD as { comments?: unknown }).comments)
Expand Down
11 changes: 6 additions & 5 deletions src/functions/OpenCapTable/stockPlan/getStockPlanAsOcf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import { readSingleContract } from '../shared/singleContractRead';

type StockPlanOcfData = Fairmint.OpenCapTable.OCF.StockPlan.StockPlanOcfData;

function damlCancellationBehaviorToNative(b: string | null): StockPlanCancellationBehavior | undefined {
if (b === null) return undefined;
function damlCancellationBehaviorToNative(b: string | null | undefined): StockPlanCancellationBehavior | undefined {
if (b === null || b === undefined) return undefined;
switch (b) {
case 'OcfPlanCancelRetire':
return 'RETIRE';
Expand Down Expand Up @@ -120,6 +120,7 @@ export function damlStockPlanDataToNative(d: Fairmint.OpenCapTable.OCF.StockPlan
receivedValue: stockClassIds,
});
}
const defaultCancellationBehavior = damlCancellationBehaviorToNative(decoded.default_cancellation_behavior);

const numeric = canonicalizeNumeric10(initialSharesReserved, { allowExponent: true });
if (!numeric.ok) {
Expand All @@ -143,9 +144,9 @@ export function damlStockPlanDataToNative(d: Fairmint.OpenCapTable.OCF.StockPlan
...(boardApprovalDate !== undefined ? { board_approval_date: boardApprovalDate } : {}),
...(stockholderApprovalDate !== undefined ? { stockholder_approval_date: stockholderApprovalDate } : {}),
initial_shares_reserved: numeric.value,
...(decoded.default_cancellation_behavior && {
default_cancellation_behavior: damlCancellationBehaviorToNative(decoded.default_cancellation_behavior),
}),
...(defaultCancellationBehavior !== undefined
? { default_cancellation_behavior: defaultCancellationBehavior }
: {}),
stock_class_ids: [firstStockClassId, ...remainingStockClassIds],
comments: decoded.comments,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,11 @@ function parseVestingPeriodCommonFields(
? damlVestingPeriodIntegerToNative(v.cliff_installment, `${fieldPath}.cliff_installment`, 0)
: undefined;

return { length, occurrences, cliffInstallment };
return {
length,
occurrences,
...(cliffInstallment !== undefined ? { cliffInstallment } : {}),
};
}

function requireVestingPeriodValue(value: unknown, fieldPath: string): Record<string, unknown> {
Expand Down
Loading