Build status
Where the testing actually stands
The product page says this in plain words. This page is the detail behind it, written for whoever on your side has to sign a pre-release build off: what is proven and where the evidence sits, what is still being checked, and what has no automated coverage at all.
The run, and what it actually measured
This page carried no figure for a while, and the reason stays on the record. The run before this one was on 31 July 2026, and every stack trace in that log named test app 0.1.0.20 while the tests in source were at 0.1.0.26. The largest group of failures in it were duplicate-key inserts, exactly the class of failure the commit in between had been written to eliminate. That run measured an old copy of the tests against the current product and described neither, so its number came down.
The current run happened on the morning of 13 August 2026, against build 0.1.0.46 with its test app in lockstep, in a Business Central 27.5 environment. It covered every test method in the source, all 662 across all 35 codeunits, scoped to Trident's whole object range and not to a list of codeunits, so nothing can drop out of scope by being left off a list:
| Ran | 662 test methods across 35 codeunits |
|---|---|
| Passed | 662 |
| Failed | 0 |
| Skipped | 0 |
Five of the 662 are newer than the run before it, and they cover the two announcements a pricing scheme's defaults now make as they are applied. One proves both fire around a normal application, once each, carrying the charter and the scheme they promise to carry. One proves a subscriber that takes the application over really does stop Trident's own defaults, with completion still announced. Two prove that a scheme Trident refuses to apply announces nothing at all. And one pins a fix the new tests forced: a scheme that clears the advance requirement used to skip the completion announcement, and no longer does. Every method that existed before them passed unchanged.
One thing on this page is about the measuring and not the product, and it belongs on a page that prints a number. Since 0.1.0.43 a run has to prove it measured the build it claims to have measured, and how many methods it counted, before it is allowed to report anything. Pointed at nothing, it fails and says so. The guard exists because on the way to that build a run reported success twice while running nothing, and a green figure over an empty suite is worse than a red one. The figures above come from a run held to it.
The run it supersedes was earlier that morning, against 0.1.0.45: 657 test methods across 35 codeunits, 657 passed, 0 failed, 0 skipped, fifteen of them the broker commission deduction: the credit memo raised against the charter fee, the checks that refuse it and report every failure in one message, the settled state that cannot be settled twice, the money lock freezing the commission fields once a charter is committed, and the closeout refusing to happen while the commission is outstanding.
The run it supersedes was earlier that morning, against 0.1.0.44: 642 test methods across 34 codeunits, 642 passed, 0 failed, 0 skipped, seventeen of them the last fourteen announcements nothing had ever listened to, on payment schedules, invoicing, document links and the workspaces. That run took the announcements Trident publishes from 22 proven to all of them, and two write-ups that turned out to say the opposite of what the code does were corrected to match the measurement, not the other way round.
The run before that was the night before, against 0.1.0.43: 625 test methods across 33 codeunits, 625 passed, 0 failed, 0 skipped, seventeen of them the sixteen announcements Trident makes as a client's advance provisioning allowance is spent, evidenced, reviewed and settled. Four of the seventeen prove that an operation Trident refuses announces nothing at all, and one pins the case a partner would have found out about at runtime: cancelling a top-up hands over a copy of a payment line that has already been deleted.
The run it supersedes was earlier that night, against 0.1.0.42: 608 test methods across 32 codeunits, 608 passed, 0 failed, 0 skipped, eight of them the announcements Trident makes when a charter changes state. Six state changes exist and two of them announced nothing, so anybody who had wired up the middle of the charter lifecycle would have found silence at runtime and no explanation for it. All six announce since that build.
The run it supersedes was earlier that night, against 0.1.0.41: 600 test methods across 31 codeunits, 600 passed, 0 failed, 0 skipped, five of them the readiness check that catches a pricing scheme charters are on and nothing can apply, described on the limitations page. One of the five exists only to prove that a scheme nobody has put a charter on is left alone, which is the failure worth guarding: a page that reports setup you do not need is a page people stop reading.
The run it supersedes was earlier that night, against 0.1.0.39: 595 test methods across 31 codeunits, 595 passed, 0 failed, 0 skipped, four of them the reason a charter's status changed. Two of those four exist only to prove that a reason given for one change never carries over to the next one, because a reason attached to the wrong line is worse for whoever reads the history than no reason at all.
The run it supersedes was the night before, against 0.1.0.38: 591 test methods across 31 codeunits, 591 passed, 0 failed, 0 skipped, five of them the invoice language arriving from the customer being billed. That build widened one permission set on purpose, and the fourteen methods that exist to catch a permission set growing wider than it should all passed unchanged alongside it.
The run before that was earlier that night, against 0.1.0.37: 586 test methods across 31 codeunits, 586 passed, 0 failed, 0 skipped, twenty-two of them the charter agreement terms. That build's first attempt was not green. A test written days earlier guards where a closeout row is allowed to send you, and a new deposit row broke it by pointing somewhere with nothing on the other side. The row moved to where it belongs, the tests that describe it moved with it, and the suite was re-run. Nothing was loosened to get that green figure, which is the only reason any figure on this page is worth printing.
The run it supersedes was earlier the same evening, against 0.1.0.36: 564 test methods across 31 codeunits, 564 passed, 0 failed, 0 skipped, thirteen of them the APA bank account and the charter VAT rate. Before that, 5 days earlier, against 0.1.0.33: 551 test methods across 31 codeunits, 551 passed, 0 failed, 0 skipped, seven of them the broker commission. Before that, against 0.1.0.32: 544 across 31 codeunits, 544 passed, 0 failed, 0 skipped, 34 written that same day. Earlier that evening, against 0.1.0.30: 536 across 31 codeunits, 536 passed, 0 failed, 0 skipped. At midday, 510 across 29 codeunits: 510 passed, 0 failed, 0 skipped, in 30 seconds.
Every test in the project passed. Trident 0.1.0.46 was compiled and tested in the same environment, and it is queued for the next pilot delivery. Nothing has gone out to a pilot yet, this build or any earlier one, so the five defects below were found and fixed before anyone could meet them.
Earlier the same day the same 492 methods ran against 0.1.0.26 and returned 491 passed and 1 failed. That one failure is the second defect below, and it was a real defect in the product. It was fixed within hours and the whole suite re-run against the fix. No test was added, removed, retitled or marked to be ignored between the two runs, and the per-codeunit method counts of the two runs are identical codeunit for codeunit. The number moved because the product changed.
Before either, on 1 August 2026, all 27 test codeunits and all 484 test methods the source held that day ran against 0.1.0.26: 482 passed, 2 failed, none skipped. Both failures were the same gap in one test's own setup, which posted a sales invoice without first making sure the company had a general posting setup for the customer and account it had picked, so Business Central refused the posting before any Trident code was reached. That was fixed and both now pass.
And a green suite is a statement about what the repository chose to assert, not a statement that the product is finished. The rest of this page is the other half of that.
The raw result file and the full per-method log are kept with the build records, not on this site. Ask and you get the files themselves, not a number.
What is not in question
| Skipped tests | None. Nothing is excluded from a run to improve the number, and no test is marked to be ignored. |
|---|---|
| Test objects shipped | None. Tests, fixtures and the scenario seed are a separate app that a customer never installs, and a static gate fails the build if one leaks into the shipping package. |
| Shipping objects | 49 pages, 37 codeunits, 36 enums, 25 tables, 4 permission sets, 2 reports and one role centre profile, all new and self-contained, plus 14 extensions to standard Sales documents, listed below. |
What Trident adds to your Sales documents
Everything else Trident installs is new and self-contained. These fourteen objects are the exception: they add Trident's fields and actions to Business Central's own sales invoice and credit memo, which is how an invoice raised from a charter stays a normal invoice your finance team already knows how to work with.
| 6 table extensions | Sales Header and Line, Posted Sales Invoice Header and Line, Posted Credit Memo Header and Line. |
|---|---|
| 8 page extensions | The matching card, subform and posted-document pages, so the charter a document came from is visible on the document itself. |
How the number is produced
Every build is compiled with no errors, no warnings, every warning treated as a failure and all three of Microsoft's analysers on, across 168 source files, and the whole suite then runs against that build in a clean Business Central 27.5 environment. The compile and the run happen in the same environment, so the figure above always describes one specific build, never a mixture.
One item further down this page has not moved: the restricted-user walkthrough is still photographed at an older build, and re-capturing it is queued behind test-environment work, not behind anything in the product.
Problems the tests found
Two of them, a day apart, both sitting on the same thing: whether a charter's payment schedule line tells the truth about money. Both were found by a test going red, both are fixed, and no build without the fixes has ever gone out to a pilot. Three more problems, found a different way, are below these two.
An unapplied payment leaves the charter saying Paid
On 5 August 2026 the six payment unapplication tests ran for the first time, against Trident 0.1.0.26 in the same container. Three passed and three failed. The three failures are one defect, and it is in the product.
After a payment is unapplied, the charter payment schedule line stays Paid when it should fall back to Posted. Business Central does its half correctly: the customer ledger entry reopens, and Trident's own check agrees the invoice is no longer fully paid. Both are asserted before the failing assertion and both pass. What never happens is the write that moves the line back. So a charter can read as paid while its invoice is open, and nothing says so.
Pressing Sync Paid Invoices on the charter corrects it at once, and no data is lost. Nobody is told to press it.
The run separates product from fixture on its own. The three passing tests call that sync by hand after unapplying; the three failing ones wait for Trident to notice by itself. One of the passing tests asserts the identical Posted status that two of the failures assert, in the same run. So the demotion code is correct and its automatic trigger does not fire on the unapplication path.
Fixed, and the fix has been run. A fix was written the same day: two pieces of code that listen for a payment being unapplied and for one being applied again, and put the schedule line back where it belongs in both directions. At 23:42 that night the six tests were run again against it. All six passed. The three that moved are exactly the three that had failed, and not a line of the tests was touched between the two runs. Raw result file and full per-method log are kept with the build records; ask and you get the files.
Merging code, packaging a build and delivering one are three different events. The first two happened on 6 August. The third has never happened, for this build or any earlier one, so the defective code has never run outside the build environment. The build queued for the next pilot delivery carries the fix, and so has every build since 0.1.0.30.
It did not mean the area was finished, and on 6 August 2026 the rest of it got tests. Five cases the six had left alone each got one, and all five ran green that evening: a payment spread across invoices belonging to two different charters demotes both, a credit memo closing an invoice in the same transaction does not count as payment, an unapplied settlement payment demotes the settlement link and blocks closeout, and a closed charter still reports the outstanding payment in review. The fifth answered a question nobody had. A reversal with no unapplication before it cannot happen, because Business Central refuses to reverse a payment that is still applied, and a test now stands guard on that refusal in case a platform update ever opens it.
A payment posted through the journal never marks the charter paid at all
Found the next morning, 6 August 2026, and it is the mirror image of the one above. The test builds a charter payment schedule line, invoices it, posts it, then pays the posted invoice through a payment journal, which is how a finance team pays an invoice. Business Central closes the invoice and Trident's own check agrees the invoice is fully paid. Both of those are asserted before the failing one and both pass. The schedule line never leaves Posted.
This is the likelier of the two to be met, because paying from the journal is the ordinary route and unapplying a payment is not. The charter reads as owing money it has already been paid. Pressing Sync Paid Invoices on the charter corrects it at once, and again nobody is told to press it.
The sibling test runs the same sequence and calls that sync by hand, and it passed throughout. So the code that marks the line paid was never wrong. What was missing was anything calling it on this route.
The fix for the unapplication defect did not cover this. The two look like one problem and they are not. That fix listens to the part of Business Central that runs when somebody uses the Apply Entries action against entries already posted. A journal line that carries its own application is applied somewhere else entirely, while the payment posts, and never reaches that code. The first fix was sound. It sat on a route this scenario never takes.
Fixed, and the fix has been run. The charter now registers a payment from every route a payment can arrive by, whichever screen or journal drove it, and the change can only mark a line paid, never unpaid. The whole suite was re-run against it instead of the one test, and every test passed.
Same footing as the one above. The fix is in 0.1.0.30 and every build since, and no build without it ever went out to a pilot, so no one has ever met a charter looking unpaid after a journal payment.
Problems found by reading the code, not by a test
Kept apart from the two above deliberately. Those went red on a machine before anybody had a view about them, which is the stronger kind of evidence. These three were caught by reading the code. Filing them under the same heading would make the measured list look longer than it is.
The second company you create gets nothing
Trident writes its setup record, its ten expense categories and its three pricing schemes into a company when it is installed there, and again when it is upgraded. Neither of those fires for a company somebody adds next month. That company came up empty, and empty is not a cosmetic state: the first person to price a charter in it got Charter pricing setup is missing and could go no further, on a tenant where everything had been working. Running more than one company in a Business Central tenant is ordinary practice, so this was a day-one failure waiting for a pilot with two.
Fixed in 0.1.0.28. A company now gets its Trident setup at install, at upgrade, and at the moment it is created, and five new tests cover the result, one of which asserts the failure itself in both directions: pricing raises the error in a company that was never set up, and stops raising it once the setup has run.
One part of that was watched and one part was not, and the difference matters more than the fix. The per-company setup was watched filling a company that had never held a single Trident record, so nothing else could have filled it in. What was not watched is the Create New Company screen driving it end to end, which needs a piece of test infrastructure still being put in place. It is why one box in the install checklist is still open.
Same footing as the two above. The fix is in every build since 0.1.0.28, and no build without it ever went out to a pilot.
A charter statement can print a blank expense category
The APA statement is what a guest settles against when a charter ends. Each line names a date, a description, an amount and the category the money went on. An APA entry written before the category list became something a customer maintains carries the old fixed category and nothing else, and the statement copied the two category fields off the entry instead of asking the entry what they resolve to. Both fields are empty on an entry like that, so a real amount printed with an empty box next to it. This was found by reading the statement code on 6 August 2026 during a scheduled review of that legacy bridge.
Fixing the statement on its own would have made it worse: for an expense nobody ever categorised, a visible blank would have become a confident wrong label on the same guest-facing line. So 0.1.0.30 guards the step before the document instead. An expense cannot be marked reviewed without a category, the error names the entries that need one, and a statement only ever contains reviewed entries, which keeps the blank off the document.
Seven tests came with it. Two on the statement, one legacy entry and one ordinary entry so the normal path is proved untouched. Two on the guard, refusing and then accepting the same entry. Three on the upgrade step that backfills these categories, which had never been testable before because it sits behind a marker that runs once by design.
What none of that proves is that any real data was repaired. The upgrade ran for real on 6 August across both companies of the test tenant, and neither holds pre-category entries, so the backfill ran over an empty set. The three tests build the old state deliberately. No real migration has happened.
Deleting a charter left its money behind
A charter can be deleted, and the only thing that used to stop one was a payment line that had already been processed. A charter whose lines were all still planned deleted cleanly while it still held APA expenses, an issued settlement statement and commercial entries. Business Central does not cascade those for you, and nothing in Trident reads them through the charter, so nothing failed and nothing warned. The rows stayed in the database naming a charter that no longer existed. Found on 6 August 2026, while reading the charter table during a review of the four permission sets.
Orphaned rows are recoverable while nobody has noticed them. The number is the expensive part. Charter numbers come off a number series or are typed in, so a freed one can be issued again, and the next charter to take it shows the previous charter's expenses and the previous charter's settlement statement, on the finance pages and on the document a guest settles against.
Fixed in 0.1.0.30. The delete now refuses on each of the three separately and the message names which one is in the way, so somebody who is stopped knows what to look at. A charter that is allowed to go now takes its status log, its APA review history and its document links with it; the same gap was orphaning those too. The right to delete the audit trail sits on the table itself and lasts only while that table's own code runs, so no user gains it and the trail still cannot be cleared by hand.
Six tests came with it. Three assert that each refusal fires on the right condition and says which one. Three assert that nothing survives a delete that is allowed. All three refusal tests failed on their first run, for a reason that had nothing to do with the guard: the error rolled the test back past its own setup, so the charter the test had just created was gone before the check ran. They were rewritten to read the error text instead, which is both the correct test and the stronger one, because the original form would have passed on any error at all.
What is not proved is that anybody has deleted a charter in a tenant that has been used. The guard has only met rows this suite created. The reused-number consequence stopped being a reading on 6 August: two tests now hand a deleted charter's number to a new charter and watch it inherit the old records, both green.
Since build 0.1.0.32 the past has a finder too. The guard refuses the next orphaning delete and does nothing about ones made under older versions, so the setup health screen now carries a warning row counting every expense record, settlement statement and audit record whose charter no longer exists, three counts shown separately. It warns and never blocks, the cleanup is still by hand, and the row gives totals, not charter numbers. Five tests cover it, green in the run above.
The review that found it came back clean on its own question. All four permission sets were read end to end. One grant cannot be reduced, so it is written up instead: the operations set needs full rights on Business Central's own attachment table, because Microsoft's attachment page writes it on the user's behalf.
Proven, with evidence on disk
Multi-blocker closeout evaluation
The workbench checklist used to case on a single cascade enum, so a charter blocked on billing reported invoice posting and payment collection as Not Applicable even when a draft invoice and an unpaid posted invoice both existed. The three billing rows are now computed from facts, mirroring how the APA rows already worked, and an APA Statement row was added. A charter now reports every simultaneous blocker.
Live non-SUPER persona proof
Three test users, each holding exactly one persona permission set and no administrator rights, were driven through the running product on 31 July 2026 at build 0.1.0.7. Fourteen screenshots and a manifest are on file with the build records. The exercise is not yet stamped against the paid-pilot evidence gate, and re-capturing it at the current build is queued behind test-environment work, not behind anything in the product.
Seven permission defects the proof found
A test can assert things about a permission set. Signing in as a genuinely restricted user and using the product is a different exercise, and it surfaced defects no unit test had caught. Each was fixed and re-proven.
| 0.1.0.7 | Three permission gaps, plus one action-affordance defect: buttons were shown to users who could not use them. |
|---|---|
| 0.1.0.14 | Dead-end states a restricted user could reach and not leave. |
| 0.1.0.15 | Indirect writes the Ops persona performs were not covered by its permission set. |
| 0.1.0.23 | Direct reads the Ops persona performs were not covered. |
| 0.1.0.24 | Finance review counting under a restricted persona. |
| 0.1.0.25 | Indirect writes on the API persona. |
| 0.1.0.26 | Direct reads on the API persona. |
Package boundary
The shipping app and the test app are separate. A static gate asserts zero Subtype = Test objects in src/, and the package inventory is checked on every release-candidate run. What a customer installs cannot contain a test, a fixture or the scenario seed.
Under test now
- Getting a build into a pilot's hands at all. This is now the single thing standing between the state described at the top of this page and a pilot running it. Every defect on this page is fixed, the suite is green against the fixed code, and the package is hashed on the install page so the file can be checked on arrival. It has not gone out yet, and no earlier build went out either, so the first install a pilot runs will carry every fix.
- Publish-as-upgrade rehearsal from a clean tenant. Upgrade code has been exercised against my own sandbox company, which is unrepresentatively test-heavy, and again on 6 August when 0.1.0.28 went on over 0.1.0.26's data. Proving it against a tenant that holds ordinary charter data is the last structural thing between here and a pilot install.
- Re-photographing the restricted-user proof at the current build. The proof was run for real, but at 0.1.0.7, and permissions changed at 0.1.0.15. Stamping screenshots taken twenty-one builds back as current evidence would be a lie, so it needs doing again, and doing it needs a browser that can reach the container. That route is closed on this machine. It waits for a different one.
- Whether the fixes hold beyond the tested paths. The new listener sits on every payment application in the customer ledger, which is the broadest hook in the product. A whole suite passing is the best evidence available that nothing regressed, and it is evidence from one seeded company, not from a real ledger with a year of history behind it.
No automated coverage yet
Listed because a reviewer should know where the gaps are, not because they are hidden.
- Payment unapplication beyond one charter at a time. This one is closed and stays listed so nobody plans around an old reading of it. The five cases the original six tests left alone all got a test on 6 August 2026 and all five went green, and they are named above. What is still true is that every one of them ran against data this suite created. A pilot ledger with a year of history behind it is a different thing, and if your charters routinely see credit notes or one payment applied across several charters, that is still the area to press on.
- API page shape at runtime. On 1 August 2026 the two pages were driven over HTTP: nineteen checks, all green, confirming Business Central serves the names the source declares and that
promoteworks end to end without double-posting when it is called twice. That run was done by hand as an administrator, which answers nothing about what an integration is actually allowed to do, so on 6 August 2026 a script covered the same ground as a deliberately restricted user and went 25 for 25. One of the 25 is knowledge nobody predicted: the API user is refused when it tries to delete its own staged rows, which is the append-only rule holding at the interface and not only in the declaration. A contract file recording the exact shape is enforced on every change too, so a rename cannot ship silently. What stays listed here is repetition. Nothing re-runs those 25 checks when either page changes, so the runtime answer is as of one evening and not as of the build you would install. The action's own logic has five tests behind it. - Evidence integrity. Origin stamping assertions, review-entry immutability negatives and cue drill-down truth are implemented but not yet asserted automatically.
- Permissions against what the code actually touches. The contents of all four permission sets are written down as a contract and enforced on every change, 285 grants and properties, and the evidence tables are held as add-only. That only catches unintended change. It says nothing about the other direction, whether each persona's grants match what its code genuinely reads and writes. That correspondence is proven only by the live persona run, which is manual and was last done at 0.1.0.7.
Documentation, now written
This section listed three unwritten documents until 31 July 2026. All three exist, and so does a fourth that was not on the list.
- Install runbook: upload, permission sets, setup, how to verify it landed, what an upgrade does to existing data, and how to take it out.
- Known limitations: what Trident does not do, what no automated test covers, and what has to change before anyone pays.
- API integration guide: the two published pages, the
promoteaction and its four outcomes, and the permissions a service account needs. - Release note 0.1.0.26: what changed since April, the six upgrade steps that touch existing data, and the known issues recorded against the build.
- Release note 0.1.0.46: applying a pricing scheme's defaults now announces itself before and after, a subscriber can take the application over, and the last named hole in the extension surface closes.
- Release note 0.1.0.45: a completed charter with a broker commission now owes a deduction document, the closeout refuses to happen until it exists, and one action creates it.
- Release note 0.1.0.44: the last fourteen announcements get their tests, every extension point Trident publishes is now proven, and three things the write-up had wrong.
- Release note 0.1.0.43: the sixteen announcements around the advance provisioning allowance that nothing had ever listened to, and the run that reported a pass while running nothing.
- Release note 0.1.0.42: the two charter state changes that told other extensions nothing, and the tests that now hold all six of them to firing once and firing on the saved charter.
- Release note 0.1.0.41: the readiness centre catching a pricing scheme your charters are on that nothing can apply, before somebody finds out by trying to price one.
- Release note 0.1.0.39: the status history recording why a charter's status changed and where the change came from, and why a change that cannot say is left saying nothing.
- Release note 0.1.0.38: the invoice language arriving from the customer being billed, the permission set that changed with it, and the guard that was rejected.
- Release note 0.1.0.37: delivery and redelivery fees, the security deposit, the crew count and the cruising area, and the checklist row that came with them.
- Release note 0.1.0.31 to 0.1.0.36: the payment split, the orphan finder, broker commission, the object rename, the APA bank account and the charter VAT rate, and what none of their test runs proves.
- Release note 0.1.0.27 to 0.1.0.30: the four builds packaged on 6 August 2026, one defect fix in each, and what none of their test runs proves.
The release note is the fourth, added the same day. It is the first one written for someone outside this project to read, and every build from here gets one. The four builds packaged on 6 August are covered by a single note because they were cut hours apart and none of them left this project. The pilot agreement is drafted but unreviewed. It goes to a lawyer alongside the licence terms and will not be used as it stands. The commercial position says what that means for anyone thinking about signing.
Deliberately out of scope
These are not roadmap items. They are things Trident will not become, listed so nobody plans around them.
- Crew rostering, maintenance scheduling, itinerary planning, an owner portal, or a CRM.
- Dashboards that summarise numbers the charter list already shows.
- Any public API surface that exists to make testing easier instead of serving a real integration.
Before a commercial release, not before a pilot
allowDebuggingistrueand must befalsefor a commercial build. It is deliberately on so a pilot can be debugged.- The legacy APA category bridge enum has to be retired, which needs a migration batch of its own.
- A real continuous-integration pipeline that compiles and tests on every change. Today that is a local script and my discipline.
- The EULA is a plain-language template and is labelled as such. It needs a lawyer before anyone signs it. A review brief has been prepared for a Dutch IT/IP lawyer, and one error it found is already flagged on the terms themselves: the establishment clause named the wrong country and the governing-law clause still names Portuguese law. Establishment is corrected. The law and forum clause has been left alone and waits for the lawyer.
If this page is what you needed
Then you are the kind of reader I wrote it for, and the useful next step is to install it and try to break it. How to get it, or write to [email protected] and say what you would want to test first.