Here's an honest place to end a build series: not at a triumphant "shipped," but at the wall. PICASSO does what I set out to make it do. It reads a copybook and derives the byte layout; it decodes and encodes real fixed-width mainframe files; it's validated three independent ways (Part 4). All of that is finished, tested, and sitting in a repository as a portable, runnable thing.
What it is not, yet, is the OutSystems Forge component that the very first post was about — the native connector the platform never had. And the gap between those two states has nothing left to do with the code.
What "done" actually means here
Everything I could build and verify without proprietary tooling is built and verified. Concretely, the repo stops at the last portable artefact: a built, tested pair of .NET libraries. Picasso.Core is the engine — the parser, the codec, the packed-decimal and EBCDIC handling — with zero OutSystems dependency. Picasso.Extension is the thin layer of action classes that wraps it for OutSystems: ParseCopybook, DecodeRecords, EncodeRecords, and the rest of the surface. Both compile and both pass their tests with nothing but dotnet build and dotnet test. No Windows required to get to here.
That was a deliberate line. Both projects target netstandard2.0 on purpose — the one framework that a plain cross-platform dotnet build can produce and that a Windows Integration Studio project can consume, with no second implementation. The whole thing is arranged so that the portable part is genuinely portable and the non-portable part is as small as it can possibly be.
The part you can't automate
But an OutSystems Extension isn't a DLL. It's an artefact you assemble in Integration Studio — a Windows-only, GUI-only tool that isn't scriptable. You open it, create the Extension, define each action, point it at the compiled DLLs, and build. There's no command-line path, no config file I can commit that turns the libraries into the packaged component. The same is true one step further along:
- The demo app that shows the parser working — paste a copybook, see the layout table, see decoded records — is built in Service Studio, OutSystems' visual development environment. Also Windows-centric, also a GUI, also not something you generate from a script.
- The Forge submission itself happens on a web form behind an OutSystems account login. Filling in the listing, the category, the icon, the screenshots — none of that is automatable from outside a real session there.
So this is where a project built and validated entirely on a Linux box hits something it can't push through by being more finished. Not a hard technical problem — a tooling boundary. The honest move was to recognise it and stop cleanly at it, rather than fake a half-step across. What I could do instead was write down the exact manual steps: the Integration Studio wiring, the demo app's screens and structures, and the Forge submission checklist — each grounded in OutSystems' own published guidance — so that when I (or someone with the right environment) sits down at a Windows machine, the crossing is mechanical rather than exploratory.
Not a hard problem — a tooling boundary. The engine is portable on purpose; the wall is a GUI, and you don't argue a GUI into being scriptable.
And which OutSystems, anyway: O11 or ODC
There's a second reason to pause before charging at that wall, and it's a genuine fork rather than a formality. "OutSystems" is now two platforms. Integration Studio Extensions — the entire path above — are an OutSystems 11 mechanism. The newer OutSystems Developer Cloud (ODC) doesn't run Integration Studio at all. So the component I've been describing reaches O11 users and no one on ODC.
Reaching ODC isn't a checkbox on the same submission — it's a second wrapper. ODC's equivalent of an Extension is an External Library, built with a standalone External Libraries SDK: a NuGet-based toolkit that decorates plain C# with attributes and packages it as a ZIP, rather than a GUI tool generating stubs. Notably, that SDK is not a Windows GUI — it's the more automatable of the two paths.
And here's where the day-one design choice pays off. Because Picasso.Core has no OutSystems dependency, it's the same engine either way. An ODC version wouldn't be a rewrite of the parser or codec; it'd be a third small wrapper project alongside Picasso.Extension, decorating the same core with the SDK's attributes. The hard part — getting the byte offsets right — is already done and shared. The wrappers are thin by construction.
Whether to build that second wrapper is a real yes/no, not a default. It's worth deciding on purpose rather than sliding into "O11 only" by omission — which is exactly why I've written it down as an open question instead of quietly picking one.
Where that leaves it
So the series ends with the engine finished and the storefront not yet open, and I'm oddly comfortable with that as a stopping point. The interesting, hard, verifiable work — turning fifty years of PIC-clause rules into byte offsets you can actually trust — is the part that's complete. What's left is packaging: real, necessary, but bounded, documented, and gated on tools and an account rather than on any question I don't know the answer to.
If you've read the whole way here: the point of PICASSO was never really the Forge listing. It was to build, and prove, the thing that should already have existed inside OutSystems — a parser that reads the copybook so a human doesn't have to reach for the ruler, native to the platform and validated to the point where I can show you exactly why it's right. That thing exists now. The last mile is a Windows GUI and an afternoon. The first five were the ones worth writing about.
The series
- The thing that should already exist
- What's actually inside a copybook
- Let the real files find the bugs
- Trust, but verify — proving it against a real compiler
- I didn't write a line of the C#
- The last mile is a Windows GUIyou are here