What you will build.
A fictional issuer prepares DEMO-ALLOCATION-01 against disclosure version D3. The digital allocation refers to D2 and the issuer register has not reconciled it. Identify those discrepancies before anyone describes the token record as an accepted investment or legally effective share transfer.
Your working record
Create a private worksheet with columns for the source reference, observed state, responsible system, observation time, expected result and unresolved issue. Use the same fictional case throughout the steps; do not paste live personal or financial records into this exercise.
Run the example before changing it.
Inspect the baseline record below. Download and read the complete JavaScript file before running it. It uses only Node’s built-in test and assertion modules; there is no package installation, account connection or secret to configure.
{
"approvedDisclosure": "D3",
"allocationDisclosure": "D3",
"eligible": true,
"registerMatched": true
}Save it as tokenized-venture-capital.mjs. Open a terminal in that folder and run:
node --version
node --test tokenized-venture-capital.mjsExpected result: four passing tests and zero failures. These tests verify the teaching classifier only. They do not verify a production integration, security boundary or financial outcome.
File or test runner will not start?
Check that Node.js 22 or later is installed, the filename ends in .mjs rather than .mjs.txt, and your terminal is in the download folder. If a managed browser blocks scripts, open “Read the full exercise” and save that text locally under the same filename. Do not disable organizational security controls.
Read the full exercise
// Hybrid-Chain offline teaching model: tokenized-venture-capital
// Fictional fields/states; NOT an API client, authorization system or production implementation.
// No network calls, credentials, payments or file writes. Review before running.
// Requires Node.js 22+. Run: node --test tokenized-venture-capital.mjs
import test from 'node:test';
import assert from 'node:assert/strict';
export function inspect(record) {
if (record.approvedDisclosure !== record.allocationDisclosure) return 'DISCLOSURE_MISMATCH';
if (!record.eligible) return 'ELIGIBILITY_REVIEW_REQUIRED';
if (!record.registerMatched) return 'REGISTER_RECONCILIATION_REQUIRED';
return 'READY_FOR_ISSUER_REVIEW';
}
const baseline = {
"approvedDisclosure": "D3",
"allocationDisclosure": "D3",
"eligible": true,
"registerMatched": true
};
const cases = [
{
"name": "review-ready fixture",
"patch": {},
"expected": "READY_FOR_ISSUER_REVIEW"
},
{
"name": "old disclosure",
"patch": {
"allocationDisclosure": "D2"
},
"expected": "DISCLOSURE_MISMATCH"
},
{
"name": "eligibility unresolved",
"patch": {
"eligible": false
},
"expected": "ELIGIBILITY_REVIEW_REQUIRED"
},
{
"name": "register mismatch",
"patch": {
"registerMatched": false
},
"expected": "REGISTER_RECONCILIATION_REQUIRED"
}
];
for (const example of cases) {
test(example.name, () => {
assert.equal(inspect({...baseline, ...example.patch}), example.expected);
});
}
Know what the tests demonstrate
- review-ready fixture
READY_FOR_ISSUER_REVIEW- old disclosure
DISCLOSURE_MISMATCH- eligibility unresolved
ELIGIBILITY_REVIEW_REQUIRED- register mismatch
REGISTER_RECONCILIATION_REQUIRED
Now change one fixture at a time. If you change a case’s input without changing its expected result, the test should fail. Read the actual-versus-expected difference and use the walkthrough to decide whether your rule or your expectation needs correcting. Keep an unchanged copy for comparison.
Work through the case, step by step.
- 01
Name the authoritative register
Do this
- Create DEMO-ALLOCATION-01 with an issuer alias, instrument description and proposed units.
- Record which issuer or registrar system determines the ownership position.
- Write a separate column for the digital asset reference; do not make it the legal register merely by labelling it on-chain.
Expected resultThe worksheet distinguishes a digital representation from the external authority that defines the instrument and ownership.
If your result is different
If there is no agreed authoritative register, pause the design; a token balance cannot settle that question.
- 02
Compare disclosure references
Do this
- Run the baseline with approvedDisclosure and allocationDisclosure both D3.
- Change allocationDisclosure to D2 and expect DISCLOSURE_MISMATCH.
- Preserve both references in the review history rather than overwriting the older document pointer.
Expected resultReviewers can see exactly which disclosure version accompanied the allocation and why a mismatch needs attention.
If your result is different
A matching document title is insufficient. Use the actual version or integrity reference maintained by the approved process.
- 03
Keep eligibility and allocation separate
Do this
- Set eligible=false and confirm ELIGIBILITY_REVIEW_REQUIRED.
- Describe where the real eligibility decision would come from and who can correct it.
- Keep private supporting documents in the protected-data workflow; the exercise uses only a fictional boolean.
Expected resultYour digital allocation view does not infer eligibility from possession of an asset or access to a document.
If your result is different
This exercise does not perform investor verification or interpret offering law. Route those determinations to the issuer's qualified owners.
- 04
Reconcile before reporting completion
Do this
- Set registerMatched=false and expect REGISTER_RECONCILIATION_REQUIRED.
- Record the discrepancy, responsible registrar and correction reference in the packet.
- Restore the fixture and retain READY_FOR_ISSUER_REVIEW; use Governance to design the versioned decision handoff.
Expected resultThe packet is ready for issuer review, without promising offering approval, exchange admission or unrestricted ownership.
If your result is different
A digital correction must not silently erase the source-register discrepancy or the disclosure history.
Review what you produced.
Save the worksheet, unmodified test output, one deliberately failing case and the explanation of its fix. A useful result includes an unresolved item with an owner; it is not just a screenshot of four green tests.
Map the model to actual systems.
The issuer and its advisers define the instrument, investor eligibility, offering documents, authoritative register, transfer restrictions, and corporate actions. Listing or admission by an external exchange is a separate process.
For each worksheet field, name the owning system, exact current operation, permission and error behavior. Put “not available” next to any missing operation and assign a dependency owner. Do not substitute the teaching classifier for that missing integration.
Open the current API reference and inspect each operation’s request, response, scope and implementation status. Code examples on this page are local models only; they do not call those operations.
Take the next technical step.
Use your worksheet and failing-case notes in the next walkthrough. Keep the same reference trail so you can see which assumptions become actual observations—and which remain dependencies.
Practice version-bound proposal review