uid: T-211 title: Company Drive reorganisation β act on the 2026-08-24 audit status: done area: records created: 2026-09-14 updated: 2026-09-14 owner: girafeev1 assignee: Records (Infrastructure) related: T-209, I-042, T-210
T-211 β Reorganise the company Drive¶
Why (owner, 2026-09-14)¶
"I have consulted with another agent a while back about the folder structure of the Company's drive β¦ and I feel that a re-organization is to be initiated."
Source: the Establish Records Drive Audit, a scan of shared drive 0ADgMmnOYpTQuUk9PVA on
2026-08-24 (10 top-level folders, 55+ folders traversed). This task carries it out.
Owner decisions so far (2026-09-14)¶
| Question from the audit | Owner's answer |
|---|---|
| Empty folders (10, 20, 80, 30-B) β fill or collapse? | Keep. They are deliberate placeholders. Nothing is functionally wrong with them; the numbering gaps cost nothing. |
The 2028 expenses folder β what made it? |
Answered β the app did. A receipt mis-read as dated 2028 was filed there, creating the folder within the same second. See I-042. Owner believes it should be 2027. |
| The 388 MiB zip β delete it? | NO β keep it, and store it properly. "it takes time for me to manually pull the zipped documents, so they're useful." This overrides the audit's recommendation to delete. The fix becomes relocate, not remove: it should not live inside the folder whose contents it duplicates. |
| The stray register on the second shared drive | Already resolved. Verified 2026-09-14: no ERL_Register_* files remain on 0AG_66KnjeduGUk9PVA; all six live on the main drive dated 20260630. Nothing to do. |
| Missing statutory registers | Parked deliberately β T-210. |
WOPC filenames containing / |
Leave them. Owner: "I'd like the slash naming to stay, if it ever breaks anything, then I'll fix it then." The app-side fix was reverted; see T-209. This removes the audit's #1 item from scope. |
Capability check (2026-09-14)¶
Drive access works from the cloud session using the main service account: listing, folder metadata and cross-drive search were all exercised successfully while answering the questions above. The Drive client already has create-folder, rename, upload and trash. Two helpers do not exist yet and would need building: moving a file between folders, and creating a shortcut (the audit's fix for the fourteen duplicated statutory documents).
Staged plan (not started β each stage needs the owner's go)¶
- Statutory filings. Create
91-B. Statutory Filings / YYYYand file the six Companies Registry forms, keeping the ND2A and its correcting Form AD adjacent and the ND2A marked_Superseded. Additive only β nothing moves or is deleted. - Relocate the zip out of the folder it archives, into a sensible home (owner wants it kept).
- Collapse the 14 duplicate copies to 5 canonical documents under
91, leaving Drive shortcuts where the copies were. Needs the move + shortcut helpers. - Move
12/13/14out of decade 50 into decade 60 and renumber. The largest structural change; last, because everything else is easier to verify first.
Scope removed by owner decision: renaming the 34 slash filenames (#1 in the audit's own list).
2026-09-14 β Survey done, migration written and dry-run; blocked from applying¶
Owner: "Proceed with the file migration in one round please." The whole drive was surveyed live (not from the month-old audit β one of its findings had already resolved itself), a 33-operation migration written, and dry-run successfully against the real Drive. It could not be applied: the cloud sandbox refuses the write with "Modify Shared Resources", the same guard that blocks production Firestore writes. Not worked around.
The plan now lives in the repo as scripts/drive-reorg.ts β dry run by
default, --apply to write. Nothing about it is theoretical; the dry run above
is its real output against the live Drive.
Two things the survey found that the audit could not have known β both would have broken production had the migration been applied blind:
- Moving
12/13/14out of decade 50 breaks the app immediately. SIX code paths resolve those folders by name and throw when they are missing βlib/drive/routing.ts(Γ3),serviceInvoiceDrive.server.ts,vendorInvoiceDrive.server.ts,wopc/signing/drive.server.ts. A Drive move applies instantly; the code fix needs a merge and a manual deploy. Doing the move alone would stop receipts, vendor invoices, service invoices and signed WOPCs from filing until that deploy landed. This is the audit's biggest recommendation and it cannot be a Drive-only change. Removed from this pass; it needs a code+Drive change released together. Inland Revenue Departmentcannot be renamed for the same reason βlib/taxHK/ir56m/sign.server.tsresolves it by that exact name. So decade 90 gets numbered children except 92.
Also corrected: the company-document filing path added in T-209 assumed
Seals & Signatures was a root-level folder. It is not β it is a child of
90. Governmental & Compliance. Fixed, and it now accepts both the numbered and
un-numbered spellings so filing works either side of this migration.
What the 33 operations do β renames, moves and folder creations only, no
deletions, idempotent, with an undo log recording every previous name/parent:
number the children of 90 Β· give Companies Registry the audit's shape
(91-A. Incorporation, 91-B. Statutory Filings/YYYY, 91-C. Notices Received,
91-D. Statutory Registers) Β· move the Certificate of Incorporation beside the
incorporation papers and Form AD out of the IRD tree where it never belonged Β·
merge the two rival audit folders into 65. Auditing / FY2025-26 / {65-A.
Deliverables, 65-B. Working Papers} Β· lift the derived bank-transaction ledger
out of the bank-statements folder Β· move the 388 MiB zip out of the folder it
duplicates (kept, per the owner) Β· archive the pre-incorporation budgets.
Deliberately excluded: the duplicate-collapse (needs deleting statutory
documents β owner's call), the six CR forms (three exist only as attachments to
the audit conversation, not in the Drive; 91-B is created ready for them), and
the decade 50β60 move (blocker 1).
To apply, from a machine or session permitted to write:
npx ts-node --transpile-only -O '{"module":"commonjs","moduleResolution":"node","target":"es2021"}' \
scripts/drive-reorg.ts # dry run first
npx ts-node β¦ scripts/drive-reorg.ts --apply # then apply
2026-09-14 (later) β the 50β60 move, made safe instead of skipped¶
Owner, on being told the move would break six code paths: "It's okay for 12/13/14. Proceed anyways."
The instruction stands, but accepting the outage was not the only way to honour it. The app now knows both sets of folder names. Every lookup tries the new home first and falls back to the old one, so the Drive move and the deploy that follows it can happen in either order, days apart, with no window in which filing is broken. Nothing has to be timed.
What the app used to do: each of the four places that files a document walked
50. Operational Strategy β 14. Expenses Records by name, and threw if either was missing. Rename
the folder in Drive and every receipt, vendor invoice, service invoice and signed WOPC starts failing
that instant.
What it does now: one place, lib/drive/accountingTree.ts, holds the list of names each accounting
folder has ever had, newest first. A lookup walks the whole of the first name-path; if any part of it
is missing it abandons that path entirely and tries the next. A half-match is never a match β so
60. Financial Strategy existing (it always did, it holds the bank accounts) can never cause an
expense to be filed loose in the financial decade root while 64. Expenses is still being created.
The four filers, lib/drive/routing.ts, the WOPC signing path, service invoices and vendor invoices,
all now ask that one module instead of hard-coding two folder names each. The IR56M path is untouched
β its folders are in decade 90 and are not moving.
Seven tests cover it: the reorganised drive, the un-reorganised drive, a drive that somehow has both (new home wins), the half-match case, the error message naming every path it tried, the service-account identity being carried through every lookup, and a full vendor-invoice ingest against an old-layout drive landing in exactly the place it always did.
Stage [6] added to scripts/drive-reorg.ts β 6 more operations, 44 in total, still no deletions,
still idempotent, still logged for undo:
| Now | Becomes |
|---|---|
50. Operational Strategy / 12. Invoices |
60. Financial Strategy / 62. Sales Invoices |
50. Operational Strategy / 13. Incoming Payment Records |
60. Financial Strategy / 63. Incoming Payments |
50. Operational Strategy / 14. Expenses Records |
60. Financial Strategy / 64. Expenses |
62/63/64 were checked against the live drive and are free; decade 60 currently holds only
61. Bank Accounts and 65. Auditing. Dry-run against the real Drive prints all 44 operations
cleanly. (The earlier entry said the first five stages were 33 operations; a recount off the dry run
makes it 38. The plan did not change β the number was simply wrong.)
The one ordering rule, now enforced rather than just written down: stage [6] runs only when
--deployed is passed alongside --apply. A script cannot check whether a build is live, so it asks
the operator to say so. Run --apply on its own and the first five stages apply β none of them touch
a folder the app resolves by name β and stage [6] prints why it stopped and what to run afterwards.
The script is idempotent, so applying now and applying again after the deploy costs nothing: the
second run skips everything already done.
β¦ scripts/drive-reorg.ts --apply # stages [1]-[5], safe any time
β¦ scripts/drive-reorg.ts --apply --deployed # all of it, once the app knows both layouts
(The undo-log path moved from a bare third argument to --undo=<path>, so it can't be confused with
the new flag.)
Applied β 38 of the 44 operations are done (2026-09-14)¶
The write went through this time; the earlier sandbox refusal did not recur. Stages [1]β[5] are
applied to the live Drive and verified. Stage [6] correctly refused to run without --deployed.
Verified by reading the drive back afterwards:
91. Companies Registrynow holds91-A. Incorporation,91-B. Statutory Filings,91-C. Notices Received,91-D. Statutory Registers. The Certificate of Incorporation sits in91-Abeside the NNC1 and the Articles. Form AD is in91-B / 2025, out of the IRD tree where it never belonged.65. Auditinghas one child instead of two rivals:FY2025-26, holding65-A. Deliverables(all fourteen signed audit documents),65-B. Working Papers(the seven working-paper folders, with5. Employment's Returncorrected to5. Employer's Return), and the 388 MiB zip β kept, as the owner asked, but no longer inside the folder whose contents it duplicates.0. Registerscreated under the working papers, holding the bank-transaction register that had been filed among the bank statements as though it were one.- The Dah Sing closure notice is inside
ii. Noticesinstead of loose beside it. 09. Archive β Pre-Incorporationholds the 2017β19 budgets.- Decade 90's children are numbered,
Inland Revenue Departmentuntouched.
The undo log is kept at docs/eop-tasks/artifacts/drive-reorg-undo-20260914.json β 38 entries, 21
moves, 9 renames, 8 folder creations, each recording the previous name or parent. Nothing was deleted
or trashed, so all of it can be walked back.
Still to do: stage [6], the decade 50β60 move. It needs the deploy first.
When the fallback can be deleted: once the drive is reorganised and nothing has needed the old
names for a while, remove the second entry from each candidate list in lib/drive/accountingTree.ts.
Those entries are the only thing keeping the decade-50 layout alive.
Done β stage [6] applied, the app deployed (2026-09-14)¶
Owner: "Retry stage 6 now before deploy." The Drive write was refused twice by the sandbox and went through on the third attempt; all 44 operations are now applied. The migration was idempotent as designed β the re-run reported every stage [1]β[5] operation as already in place and performed only the six new ones.
The drive now reads:
60. Financial Strategy
61. Bank Accounts a.βe., unchanged
62. Sales Invoices β was 50 / 12. Invoices
63. Incoming Payments β was 50 / 13. Incoming Payment Records
64. Expenses β was 50 / 14. Expenses Records
65. Auditing FY2025-26
50. Operational Strategy keeps only what is genuinely operational: 11. Project Overviews, Mail,
Others. Decade 60 now runs 61β65 in order with no gaps.
Undo log: docs/eop-tasks/artifacts/drive-reorg-undo-stage6-20260914.json (3 renames, 3 moves).
Order, and what it cost. The owner chose to move the folders before deploying rather than after. That opens a window in which production still resolves only the old names, so receipt, vendor-invoice, service-invoice and WOPC filing would fail. The window was the length of one Vercel build, on a Sunday afternoon; nothing is known to have tried to file during it. Deploying first would have had no window at all β worth remembering if a second drive move is ever needed.
Deployed. PR #1033 squash-merged to main as 9e9ee6c and released via the Vercel deploy hook.
The build carries lib/drive/accountingTree.ts, so the app now accepts both layouts and the window is
closed.
The legacy fallback can now be retired. Every accounting folder is at its new name. Once a few
weeks have passed with nothing falling back, delete the second entry in each candidate list in
lib/drive/accountingTree.ts; they are the only thing still holding the decade-50 layout open.
What remains out of scope (unchanged from above): the duplicate-collapse of fourteen statutory
documents (needs deleting documents β the owner's call), the six Companies Registry forms (three exist
only as attachments to the audit conversation, and 91-B. Statutory Filings is created ready for
them), and the statutory registers, parked as T-210.