What you will build.
Review fictional grant instruction DEMO-GRANT-01. The applicant is eligible, but approval or provider payment may still be pending. Keep eligibility, an authorized instruction and disbursement evidence separate while protecting the applicant's case documents.
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.
{
"eligible": true,
"approved": true,
"providerState": "confirmed"
}Save it as public-sector-disbursements.mjs. Open a terminal in that folder and run:
node --version
node --test public-sector-disbursements.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: public-sector-disbursements
// 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 public-sector-disbursements.mjs
import test from 'node:test';
import assert from 'node:assert/strict';
export function inspect(record) {
if (!record.eligible) return 'ELIGIBILITY_REVIEW_REQUIRED';
if (!record.approved) return 'APPROVAL_REQUIRED';
if (record.providerState !== 'confirmed') return 'PAYMENT_UNRESOLVED';
return 'DISBURSEMENT_RECORDED_FOR_REVIEW';
}
const baseline = {
"eligible": true,
"approved": true,
"providerState": "confirmed"
};
const cases = [
{
"name": "provider record present",
"patch": {},
"expected": "DISBURSEMENT_RECORDED_FOR_REVIEW"
},
{
"name": "eligibility unresolved",
"patch": {
"eligible": false
},
"expected": "ELIGIBILITY_REVIEW_REQUIRED"
},
{
"name": "instruction not approved",
"patch": {
"approved": false
},
"expected": "APPROVAL_REQUIRED"
},
{
"name": "payment pending",
"patch": {
"providerState": "pending"
},
"expected": "PAYMENT_UNRESOLVED"
}
];
for (const example of cases) {
test(example.name, () => {
assert.equal(inspect({...baseline, ...example.patch}), example.expected);
});
}
Know what the tests demonstrate
- provider record present
DISBURSEMENT_RECORDED_FOR_REVIEW- eligibility unresolved
ELIGIBILITY_REVIEW_REQUIRED- instruction not approved
APPROVAL_REQUIRED- payment pending
PAYMENT_UNRESOLVED
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
Separate eligibility from payment instruction
Do this
- Record DEMO-GRANT-01 with independent eligibility and approval fields.
- Keep supporting documents behind their own access controls; use a permitted reference in the worksheet.
- Name who decides eligibility, who approves the instruction and who operates the payout route.
Expected resultAn eligible case is not automatically a payment authorization or proof that a bulk-payment route is enabled.
If your result is different
If one status field currently covers all three decisions, split it before mapping the program workflow.
- 02
Test the two decision boundaries
Do this
- Run the baseline and then set eligible=false; expect ELIGIBILITY_REVIEW_REQUIRED.
- Restore the fixture and set approved=false; expect APPROVAL_REQUIRED.
- Record each decision's version or reference and its responsible reviewer in the real integration plan.
Expected resultThe design can explain whether a case is awaiting program review or an authorized disbursement instruction.
If your result is different
Do not let a payment notification override an unresolved eligibility or approval record; investigate the mismatch.
- 03
Inspect the actual payment stage
Do this
- Set providerState=pending and confirm PAYMENT_UNRESOLVED.
- Keep the provider reference and observation time visible to the authorized case operator.
- Define the support and reconciliation action without marking the applicant paid prematurely.
Expected resultAn approved instruction and a confirmed provider payment remain separate milestones.
If your result is different
When the provider response is lost, reconcile the existing instruction before considering another disbursement.
- 04
Preserve appeals and corrections
Do this
- Add a manual appeal row linked to the original case rather than overwriting its history.
- List what information can be included in an oversight report without revealing applicant circumstances.
- Use Governance to plan version-bound decisions and Data Vault for protected supporting evidence.
Expected resultThe review packet is useful for program oversight without claiming to determine statutory eligibility or create a payment rail.
If your result is different
A public proof must not contain private case narratives merely because an auditor may need them in an authorized private process.
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 program and its authorized providers own eligibility policy, appeals, recipient support, disbursement rails, safeguarding, and oversight requirements.
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 the versioned approval workflow