← BBS SG Bank submission · All documents

01 — Modernization Journal (BBS SG Bank COBOL → Modern)

System: BBS SG Bank daily batch (accounts.dat + operations.dat, line-sequential). Scope: legacy/bank.cobmodern/bank.py, parity-checked by scripts/benchmark.py, wrapped by the demo app in site/. Owner of this doc: {TEAM_NAME}. Last updated: 23 September 2026 (2026-09-23).

How to read this file. This is a truthful journal. A step is only ✅ when its evidence cell points at something a judge can re-run today. Steps without evidence are ⛔ Pending (not started) or 🚫 Blocked (waiting on a named prerequisite). No Opsera Forge output is written down that we did not actually obtain. No speedup is stated that we did not actually measure. Line numbers were checked on 2026-09-23. This is a shared workspace; re-verify before submission.

Status legend: ✅ Verified · 🟡 In progress · ⛔ Pending · 🚫 Blocked · ❌ Failing · ➖ N/A.


Phase 0 — Assessment (understand the legacy)

#StepStatusEvidenceNotes
0.1Locate and read the legacy batchlegacy/bank.cob, 172 linesFree-format COBOL (GnuCOBOL). Its own header (L2-29) documents the data layout and the O(m×n) cost.
0.2Identify data contractsbank.cob L34-48 (select/FD), L89-92 (operation offsets)accounts.dat: acct = cols 1-8, balance = cols 10-21 (PIC 9(12)). operations.dat: kind=col 1, from=3-10, to=12-19, amount=21-32.
0.3Identify the performance bottleneckbank.cob L108 ("reopen and scan... for every operation"), L133 ("rewrite every account for every accepted operation")Two nested full-file loops ⇒ O(operations × accounts); plus a temp-file copy each accepted op.
0.4Confirm legacy validation rulesbank.cob L94-97 (amount), L99-103 (kind), L105-108 (self-transfer), L114-132 (existence/funds)Rules: numeric & non-zero amount; kind ∈ {D,W,T}; no self-transfer; source/dest must exist; non-deposit needs funds; malformed line ⇒ rejected, not fatal (header L26-28).
0.5Run Opsera Forge Assessment on the legacy codeForge project 6de0abcc-… (from /tmp/bbs-sg-legacy.zip); Assessment complete — ForgeScore 57/100 (Developing), 10 findings incl. 3 high (O(m×n) scans, full-file rewrites, missing specs)Score/findings read from the signed-in UI, 2026-09-23. See 04-forge-pipeline-mapping.md §Stage 1.
0.6Confirm GnuCOBOL toolchain for parity runsscripts/get_cobc.sh → GnuCOBOL 3.2.0 at /tmp/gcb-build/install/bin/cobcUnblocks 5.1-5.2.

Assessment summary (our own analysis, not a Forge output): the program is I/O-bound, not CPU-bound. Per operation it performs one full scan to find/validate the accounts and then two full passes to rewrite the file through a temp file. Cost scales with operations × accounts, so higher transaction volume degrades super-linearly.


Phase 1 — Intent

#StepStatusEvidenceNotes
1.1Draft modernization intentThis doc, "Intent" block belowWritten by the team.
1.2Generate/record Forge Intent artifactdocs/forge/intent.md, SHA-256 8510138776e8…94ccIntent v1 approved in the signed-in UI and downloaded (2026-09-23); full hash in docs/forge/README.md. Artifact id 0e0655e7-62be-4351-b2c3-b954feb6c49b. Map in 04-... §Stage 2.

Intent (team-authored): Preserve exact BBS SG Bank batch semantics while removing the per-operation full-file scan/rewrite. Modernize to an indexed, single-write batch, keep the on-disk formats byte-compatible so downstream consumers are unaffected, and make the behaviour continuously re-verifiable by an automated parity test.


Phase 2 — PRD / Spec

#StepStatusEvidenceNotes
2.1Write functional requirements03-requirements-and-acceptance-tests.md FR-1…FR-10Derived from bank.cob behaviour.
2.2Write non-functional requirements03-... NFR-1…NFR-5Linearity, single write, stdlib-only, robustness.
2.3Generate/record Forge PRD-Spec artifactdocs/forge/prd.md, SHA-256 8b138ae25790…3453PRD-Spec v1 generated (reported ~95% confidence), approved, and downloaded (2026-09-23); exported. Map in 04-... §Stage 3.

Phase 3 — Architecture

#StepStatusEvidenceNotes
3.1Design the modern algorithmmodern/bank.py L10-47Load accounts.dat into a dict once → apply ops with O(1) lookups → write once.
3.2Preserve on-disk formatbank.py L11-18, L44-46Pipe layout is byte-compatible with the fixed-column layout the legacy program reads (see 02-before-after.md §2).
3.3Capture Forge Architecture artifactdocs/forge/architecture.md, SHA-256 d0be1c535a37…058bArchitecture v1 completed (reported ~100% confidence), approved and downloaded (2026-09-23). Map in 04-... §Stage 4.
3.4Decompose into Forge User Stories / work ordersdocs/forge/work-orders.md, SHA-256 a78ac60579ae…cd0d2User Stories v1: 6 epics / 33 proposed stories, ~75% reported confidence, approved and downloaded (2026-09-23). Proposed work, not implemented. Map in 04-... §Stage 5.

Architecture decision record (team-authored):

path, not a reimplementation (site/backend/service.py header).


Phase 4 — Implementation

#StepStatusEvidenceNotes
4.1Legacy program in repolegacy/bank.cobProvenance/authorship not recorded here — do not over-claim.
4.2Indexed modern implementationmodern/bank.py L10-47run() returns (processed, rejected, total).
4.3Output contract preserved (PROCESSED/REJECTED/TOTAL_CENTS)bank.py L52-54Same 8/8/16-digit zero-padded lines as bank.cob L84-86.
4.4Malformed-row robustness (reject-and-continue)bank.py L23-25 (len(parts) != 4 or len(parts[3]) != 12 or not parts[3].isascii() or not parts[3].isdigit()rejected)Matches the legacy header's promise (L26-28). Closes former AT-11.
4.5Fictional demo web app over the real enginesite/backend/app.py (303 lines), site/frontend/index.html (489 lines)Stdlib-only HTTP server; site/backend/service.py (508 lines) wraps modern/bank.py. Smoke-tested 2026-09-23.
4.6Forge-driven implementation of the modern enginemodern/bank.py is team-authored local codeForge did not generate the modern Python. Forge produced the Assessment and the exported Intent v1, PRD-Spec v1, Architecture v1, User Stories v1 and Testing v1 planning documents. The 33 stories and 132 test cases are proposed, not implemented or executed.

Phase 5 — Testing (parity + acceptance)

#StepStatusEvidenceNotes
5.1Legacy↔modern parity run (identical rows, counts, totals)scripts/evidence/benchmark-1200x400.txt, benchmark-5000x500.txt, benchmark-sweep.txt all report parity: … byte-identical accounts.dat: YESVerified 2026-09-23 with isolated GnuCOBOL 3.2.0.
5.2Measured speedupmedian 1.003951s → 0.035133s = 28.6x (1200×400); median 4.727858s → 0.036914s = 128.1x (5000×500, synthetic)See 02-before-after.md §6 for the required synthetic-workload disclosure.
5.3Automated tests (modern engine)tests/test_modern.pyRan 5 tests … OK (2026-09-23)Covers deposits/withdrawals/transfers, overdraft/unknown/self-transfer, malformed-row continuation, and the duplicate-ID / 12-digit-overflow safety divergence.
5.4Acceptance tests AT-1…AT-11 (modern behaviour)Re-run per 03-...; outputs captured thereVerified 2026-09-23.
5.5Legacy/parity contract suitescripts/test_bank.pyRan 33 tests … OK (3.2s)Unit tests (fixture generator, metrics parser), legacy contract tests, parity tests, characterization tests (incl. the duplicate-ID / overflow divergence), end-to-end benchmark test. Skips legacy cases if cobc is absent.
5.6Demo-site test suitesite/tests/50 tests (service, HTTP API, frontend wiring)Confirms the site calls the unmodified engine.
5.7Operator-terminal test suitelegacy-ui/tests/test_terminal.pyRan 20 tests … OKIncludes one genuine COBOL batch run and the headless interaction walkthrough; see 6.7.
5.8Forge Testing artifact linkeddocs/forge/testing.md, SHA-256 19749260605e…92b3Testing v1: 132 proposed test cases (33 functional / 33 smoke / 33 regression / 33 performance), generated and exported — not approved (no Approve action shown). A generated planning artifactnot 132 executed tests; the local executable suites remain 108 passing. Map in 04-... §Stage 6.

Phase 6 — Delivery

#StepStatusEvidenceNotes
6.1Demo app runs locallypython3 site/backend/app.py --port 8791; GET /api/health{"status":"ok","fictional":true}; GET / → 200Verified 2026-09-23.
6.2Hosted prototype deployed to a public URLplaceholder https://bbs-sg-bank-demo.pages.devRequired for submission. The app is deployable; only hosting remains.
6.3Short demo recorded (≤3 min)placeholder https://bbs-sg-bank-demo.pages.dev/media/bbs-sg-bank-demo.mp4Script ready in 05-demo-script.md.
6.4Before/after write-up02-before-after.mdComplete, evidence-linked.
6.5Per-teammate public post{MEMBER_n_POST_URL}Outlines ready in 06-social-posts.md.
6.6Submission checklist signed🟡07-submission-checklist.mdOpen gates: public hosting, demo recording, per-member posts, and the raw Assessment export.
6.7Operator terminal runs the real COBOL batchlegacy-ui/Live 1,200×400 job: 400 processed, 3 rejected, 1.197 s actual COBOL execution (1.234 s overall), matching the modern engine's TOTAL_CENTS 5489403400. Synthetic fixture; deliberately inefficient legacy design.
6.8Forge Intent, PRD-Spec, Architecture, User Stories + Testing v1 exporteddocs/forge/Intent, PRD-Spec, Architecture and User Stories were approved in the signed-in UI and downloaded; Testing v1 was generated/exported but not approved (its browser page showed no Approve action). SHA-256 in docs/forge/README.md. User Stories = 6 epics / 33 proposed stories; Testing = 132 proposed cases (not executed). Assessment raw report still unexported; Delivery pending.

Blocked-work register (what unblocks us)

Blocked stepPrerequisiteAction
5.1, 5.2GnuCOBOL cobcResolved 2026-09-23: isolated GnuCOBOL 3.2.0 built by scripts/get_cobc.sh; parity and timings captured under scripts/evidence/.
Export remaining Forge artifacts (raw Assessment report, Delivery)Forge artifact-export credentialForge project already created; Assessment complete (raw report unexported; docs/forge/assessment.md is a team transcript); Intent v1, PRD-Spec v1, Architecture v1 and User Stories v1 approved and downloaded, and Testing v1 generated and downloaded (no Approve action shown), to docs/forge/. The supplied MCP forge_ token returns HTTP 401 Invalid or revoked token, but signed-in browser downloads work (that is how the exports were retrieved). Use browser downloads for the rest, or issue a fresh token (Profile → API Tokens).
6.2Public hosting targetDeploy site/backend/app.py; set https://bbs-sg-bank-demo.pages.dev.
6.3, 6.5Recording + publishingFollow 05-/06-; set the placeholder URLs.

Evidence log (append-only)

DateCommand / artifactResult
2026-09-23python3 modern/bank.py <fixture> (2 accounts, 7 ops incl. 3 edge cases)PROCESSED=00000003, REJECTED=00000004, TOTAL_CENTS=0000000000000230; balances …160, …070
2026-09-23python3 tests/test_modern.pyRan 5 tests … OK
2026-09-23python3 site/backend/app.py --port 8791/api/health, /api/summary, /api/benchmark, /health ok; summary invariant_ok: True, engine modern/bank.py; benchmark modern 0.0336s (300 ops), legacy unavailable, speedup: null; / → 200
2026-09-23which cobcnot found → parity/perf blocked
2026-09-23python3 scripts/benchmark.pyerror: GnuCOBOL is required: install cobc first
2026-09-23Forge UI: created project 6de0abcc-… from /tmp/bbs-sg-legacy.zipproject URL recorded; ZIP contains bbs-sg-legacy/bank.cob, SHA-256 f4730e6d2b3867a5d8908a6dc0f77e714826f15d23118a3f8e42d7f0b2afc21d
2026-09-23Forge UI: Assessment / ForgeScoreobserved generating at the time; later completed — see the Assessment-complete row below
2026-09-23Forge MCP with supplied forge_ tokenHTTP 401 Invalid or revoked token → machine export blocked (UI still usable)
2026-09-23shasum -a 256 legacy/bank.cob (working tree)74669316…446f467differs from the uploaded copy (f4730e6d…afc21d) because of later header edits; the Forge assessment reflects the uploaded revision
2026-09-23/tmp/gcb-build/install/bin/cobc --versioncobc (GnuCOBOL) 3.2.0
2026-09-23scripts/test_bank.py (with isolated cobc)Ran 33 tests in 3.194sOK
2026-09-23tests/test_modern.pyRan 5 testsOK (includes duplicate-ID rejection and 12-digit-overflow rejection)
2026-09-23site/tests/50 tests (service, HTTP API, frontend wiring)
2026-09-23scripts/evidence/benchmark-1200x400.txtparity YES; median legacy 1.003951s vs modern 0.035133s = 28.6x; PROCESSED 400, REJECTED 3, TOTAL_CENTS 120001200
2026-09-23scripts/evidence/benchmark-5000x500.txtparity YES; median legacy 4.727858s vs modern 0.036914s = 128.1x; PROCESSED 500, REJECTED 3, TOTAL_CENTS 499999475 (synthetic workload)
2026-09-23scripts/evidence/benchmark-sweep.txtspeedup grows with accounts: 300→4.3x, 600→8.0x, 1200→13.1x, 2400→24.6x; all parity ok
2026-09-23Forge UI: Assessment completeForgeScore 57/100 (Developing); 10 findings incl. 3 high (O(m×n) scans, full-file rewrites, missing specs)
2026-09-23Forge UI: goals sent + Apply & RegenerateIntent v1 generation initiated; later completed — see row below
2026-09-23scripts/benchmark.pyextended to ≈350 lines with a parity_ok gate; later run the same day on the isolated compiler (rows below)
2026-09-23Forge UI: Intent v1 completeartifact id 0e0655e7-62be-4351-b2c3-b954feb6c49b in the signed-in UI; later approved and downloaded — see rows below. The modern Python remains team-authored; Forge authored the planning document only.
2026-09-23Forge UI: PRD-Spec clarification submittedclarification submitted; PRD-Spec generation started (later completed and exported — see rows below)
2026-09-23legacy-ui/tests/test_terminal.pyRan 20 tests … OK; includes one genuine COBOL batch run
2026-09-23legacy-ui/ live job, preset M (1,200 accounts × 400 ops) via real legacy/bank.cobPROCESSED 400, REJECTED 3; actual COBOL execution 1.197 s (1.234 s overall); modern TOTAL_CENTS 5489403400 matched (synthetic fixture, deliberately inefficient legacy design)
2026-09-23Forge UI → browser download: Intent v1 approveddocs/forge/intent.md; SHA-256 8510138776e896681e3621124aea049e82f20fdb5948432d811ff4d96ecf94cc (verified)
2026-09-23Forge UI → browser download: PRD-Spec v1 generated (~95% reported confidence), approveddocs/forge/prd.md; SHA-256 8b138ae25790357ffb623c8a53f6efe8ee9d7a355fa239657dc80c428fa63453 (verified)
2026-09-23Forge UI: Architecture clarification answeredArchitecture generation underway at the time; later completed and exported — see rows below
2026-09-23Forge UI → browser download: Architecture v1 completed (~100% reported confidence), approveddocs/forge/architecture.md; SHA-256 d0be1c535a3727558143ba7e872813925a2908efb02477bec251b92a4cb7058b (verified)
2026-09-23Forge UI: User Stories generation underwaygeneration underway at the time; later completed and exported — see rows below
2026-09-23docs/forge/assessment.md (team transcription)records the observed Assessment values (ForgeScore 57/100, 10 findings incl. 3 high, 3 high findings named); the raw Forge report remains unexported
2026-09-23Forge UI → browser download: User Stories v1 (~75% reported confidence), approveddocs/forge/work-orders.md; 6 epics / 33 proposed stories; SHA-256 a78ac60579ae7224d6888e166e211e23ef270eccddb0e22632916766312cd0d2 (verified). Proposed work, not implemented.
2026-09-23Forge UI → browser download: Testing v1 generated and exported (not approved — no Approve action shown)docs/forge/testing.md; 132 proposed test cases (33 functional / 33 smoke / 33 regression / 33 performance); SHA-256 19749260605e3e1bd85539f069c47db9b06cdddcbdde3b9d85676c41e91d92b3 (verified). A generated planning artifact, not 132 executed tests; local executable suites 108 passing (33 + 5 + 50 + 20).
2026-09-23Forge MCP with supplied forge_ token (re-checked)still HTTP 401 Invalid or revoked token; signed-in browser downloads work, used for the Intent/PRD-Spec/Architecture/User Stories/Testing exports
2026-09-23scripts/evidence/benchmark-final-5000x500.txt (three timed runs, one warm-up)parity YES; median legacy 4.723607s vs modern 0.040941s = 115.4x, PROCESSED 500, REJECTED 3, TOTAL_CENTS 499999475; variation from prior 128.1x on the same deliberately inefficient synthetic baseline