## 2026.10.15 ### Highlights - Quotes, invoices, payments and receipts are also kept as rows, and each is checked to the cent against what was issued. (#8, #11, #33) - An invoice takes its number (INV-YYYY-M-N) when it is finalised, and an issued invoice is corrected by a credit note and a new invoice, never changed in place. (#39, #45, #47) - One email can carry several issued documents, Send can be undone for 10 seconds, and the job lists every email as it went out. (#59, #64, #67, #69) - Sentry reports errors, frustration and slow screens, and it never receives customer data, document numbers or money amounts. (#42, #62, #83) - Owners connect Field to their own Xero app with a 4-step wizard in Settings, Integrations, and each issued invoice makes a matching draft in Xero with Field's PDF. (#94, #96, #107, #115, #132, #134) - Milestone defaults and caps come from account rules by region and contract value. (#106) - Field publishes verifiable releases to npm, GHCR and GitHub Releases, and an operator can run a pinned release that refuses to install unless it verifies. (#120, #121, #136) ### Changes - The business profile comes from configuration, so a production installation can deploy from this repository. (#9) - Every quote version is also rows, verified to the cent. (#8) - Quote documents and totals come from the quote rows. (#11) - Issued documents can also be kept in a locked R2 bucket. (#13) - The business trading name is optional; documents use the legal name without one. (#23) - Invoices, payments and receipts are also rows, verified against what was issued. (#33) - Sentry reports every error, frustration and slow screen without customer data. (#42) - Invoices are issued from the sequence (INV-YYYY-M-N) when they are finalised. (#39) - An issued invoice is corrected by a credit note and a new invoice, never revised in place. (#45) - Milestone invoices are tax invoices with one claim line per milestone; receipts take RCT-YYYY-M-N. (#47) - One email carries several of the job's issued documents, by uid. (#59) - The email composer follows Field's design system, with a preview built by the send. (#64) - Send can be undone for 10 seconds, drafts are kept on the server, and the job lists every email as it went out. (#67) - Replacement invoices attach their adjustment note by default, and follow-ups join the earlier Gmail conversation. (#69) - Owners settle legacy invoice amounts on a screen, not the browser console. (#88) - Owners connect Field to their own Xero app in Settings, Integrations. (#94) - A Replit publish only builds a commit that passed GitHub CI, and main requires passing checks. (#111) - Issued invoices create matching drafts in the owner's Xero, with Field's PDF. (#96) - Field's invoice prints its job and quote, as its Xero invoice's reference does. (#107) - Owners enter integration credentials in Settings, stored encrypted per organisation. (#115) - A new installation has no business identity by default. (#123) - Field publishes verifiable CalVer releases to npm, GHCR and GitHub Releases. (#120) - Operators run a pinned Field release that refuses to install unless it verifies. (#121) - FIELD_SECRETS_KEY can be a 40-character password from a password generator. (#126) - Field's releases are named and channelled as openclaw/openclaw's are. (#136) - Connect Xero is a 4-step wizard that makes the encryption key in the browser. (#132) - Settings, Integrations is a catalogue of cards; Xero opens its wizard or Configure. (#134) - Milestone defaults and caps come from account rules by region and contract value. (#106) ### Fixes - GST rounds up on exactly half a cent. (#3) - Databases sharing a PostgreSQL server migrate at the same time. (#5) - A catalogue write queued behind another reads the clock after it. (#19) - Npm installs from the lockfile's URLs, so Replit builds don't 404. (#25) - The jobs board shows each quote's real total. (#31) - Every job on disk appears on the jobs board. (#34) - The Replit workspace pulls main without a GitHub token. (#37) - Production backfills quote and invoice rows at boot, and owners dry-run data migrations in the app. (#38) - Sentry never receives a request's query string from a traced request. (#62) - Legacy invoices take the amounts Field emailed, and an owner settles the rest. (#61) - Scripts/backfill-db.js runs again, importing server/db/job-backfill.js. (#49) - Sentry no longer receives document numbers or money amounts. (#83) - People can pinch-zoom Field on a phone. (#85) - Scripts/backfill-db.js --apply refuses Field's own database. (#53) - An owner can settle a superseded legacy invoice that was paid after its revision. (#86) - The invoice backfill takes a missing issue time from the job's records, and the dry run shows why a milestone is refused. (#90) - A Replit publish deploys GitHub main, not the workspace files. (#92) - Email rendering and the client have no known high advisory in shipped code, and Dependabot raises updates. (#95) - The jobs board answers when one job's files cannot be read in time. (#109) - Reading a job no longer re-hashes every file of every generation it has. (#110) - Publish fetches arcforgelabs/field, the repository's new home, not the old name's redirect. (#114) ### Complete contribution record This audited record covers the complete history through 1b602271d5b566883477d9978381fb6ac4f7686f: 62 in-range PRs + 0 retained seed-only PRs = 62 unique PRs. The generation manifest also supplies direct commits as editorial input; the grouped notes above prioritize user impact. #### Pull requests - **PR #3** Related #2. - **PR #5** Related #4. - **PR #9** Related #7, #1. - **PR #8** Related #6. - **PR #11** Related #10. - **PR #13** Related #12. - **PR #18** Related #17. - **PR #19** Related #16. - **PR #21** Related #20. - **PR #23** Related #22. - **PR #25** Related #24. - **PR #26** - **PR #15** Related #14. - **PR #31** Related #30. - **PR #33** Related #27. - **PR #34** Related #32. - **PR #35** - **PR #37** - **PR #38** Related #36. - **PR #42** Related #41. - **PR #39** - **PR #62** - **PR #45** - **PR #47** Related #28. - **PR #61** Related #60. - **PR #59** Related #58, #50. - **PR #64** Related #63. - **PR #67** Related #66, #51. - **PR #69** Related #68. - **PR #49** Related #48. - **PR #72** Related #65. - **PR #83** Related #71. - **PR #85** Related #84. - **PR #53** Related #52. - **PR #44** Related #43. - **PR #86** - **PR #90** Related #89. - **PR #88** - **PR #92** Related #91, #87. - **PR #95** Related #78. - **PR #94** - **PR #109** - **PR #110** - **PR #113** - **PR #114** - **PR #111** Related #108. - **PR #96** - **PR #107** - **PR #119** - **PR #115** Related #112. - **PR #125** Related #124. - **PR #123** Related #122. - **PR #118** - **PR #117** - **PR #120** - **PR #127** - **PR #121** - **PR #126** - **PR #136** - **PR #132** - **PR #134** - **PR #106** Related #29.