- [Workspace repos](workspace_repos.md) — three independent git repos under `/config/workspace/`: evolution (ERP), portal (mobile PWA), apps (external API/public apps)
- [Portal: no JS build, hand-maintained min/nomin](portal_minified_no_build.md) — runtime loads `.min.js`; edit both min+nomin or the fix ships dead; live entry is `index.php`→`offlineScripts.min.js`
- [Evolution workspace mapping](evolution_workspace_mapping.md) — `/config/workspace/evolution/` is shared between code-server and a dev LAMP stack on the same host; production syncs via git + external DB tool
- [Code-server setup scripts](codeserver_setup_scripts.md) — `/config/workspace/codeserver-setup/{install,extensions}.sh` rehydrate the container with PHP/MariaDB/lint tooling and VS Code extensions after redeploy
- [Dev MySQL access](dev_mysql_access.md) — direct MariaDB from code-server: host `192.168.20.35`, user `claude`, pw = .env root; install.sh backs up memory to persist redeploys
- [Reports: no second pageheader](feedback_reports_no_pageheader.md) — `report.inc` already renders the global pageheader; use a styled title row inside the report instead
- [Session token hygiene](feedback_session_token_hygiene.md) — cost is dominated by marathon sessions; proactively suggest /clear per-ticket and /compact at ~40-50% context
- [Docs authoring](docs_authoring.md) — how to add a page to `evolution/docs` (bootstrap+template pattern) and hand-edit the sidebar section nav
- [Evolution permission system](evolution_permission_system.md) — `mod_*` session vars (0/1/2): set in staffedit→permissions table, loaded at login by login2save.php, enforced per-screen; changes need re-login
- [Evolution sort-injection validator](evolution_sort_injection_validator.md) — registers must run sortby/sortdir through `safeOrderBy`/`validateSortby` in functions.php; raw `ORDER BY $_REQUEST[sortby]` is SQLi (shopify plugin still unguarded)
- [Evolution BOM hierarchy](evolution_bom_hierarchy.md) — bom→quoteitems_bom→jobInventory_bom override chain; referenceId=quote item id; resolver is library/inventory.php::getChildren()
- [Evolution AJAX *Save auth gate](evolution_ajax_save_auth_gate.md) — `checkSession()` is login-only, doesn't block; data-returning `*Save.php`/`app/ajax` handlers need an explicit `mod_*` gate (reports → `mod_rep`)
- [Evolution timesheets.invoiced is an invoice id](evolution_timesheets_invoiced_column.md) — `invoiced` stores the invoice id not a 0/1 flag; test `> 0` for invoiced, `= 0` for unbilled; never `= 1`
- [Evolution addressbook account history](evolution_addressbook_account_history.md) — contact employment journey lives in `addressbook_account_history` (dated spans); `cmoveaccount` writes it; rendered as timeline in addressbookedit.inc
- [Evolution GL/P&L data model](evolution_gl_pl_data_model.md) — accountcats P&L type ids (1/5/6/7), gledger posting signs (income credit, cogs/expense debit), the branch-0 quirk + fix, and accrual/cash P&L basis
- [Two accounting.php files](evolution_two_accounting_files.md) — web-root globals (live invoice/bill commit) vs library/ class (payments/xero); patch BOTH for GL posting changes
- [GST high-precision project](gst_precision_project.md) — per-rate header tax (more accurate than Xero); Phase 1+2 done/verified, Phase 3 code done unverified, Phase 0+4 pending; open taxSell mapping issue on inv 59861
- [importQuote tax drift + taxSell gotcha](evolution_importquote_tax_drift.md) — approach REVERSED to preserve 4dp + per-rate header; taxSell override can zero a line's GST when inventory.taxSell unset (inv 59861 root cause)
- [Float money columns lose cents](evolution_float_money_columns.md) — invoiceitems.total/adjPrice are single-precision FLOAT; drop cents above ~$8.4M → Xero drift; sum via ROUND(CAST(adjPrice AS DECIMAL(15,4))*qty,2)
- [Xero AP payment sync](evolution_xero_ap_payment_sync.md) — bills store raw GUID (invoices serialized); getPayments needs the GUID in $where; commitPayments AP branch is dead, use commitBillPayments; AP control acct = getPref('accPay') not hardcoded 43; paymentDetail AP uncommit/commit/delete
- [Xero payment externalRef](evolution_xero_payment_externalref.md) — payment.externalRef = raw Xero payment GUID; putPayment now stamps it on send (was missing→delete no-op'd); delete pre-flights Xero before GL uncommit & aborts on failure; deletePayment takes GUID directly
- [Xero deleted-payment sweep + AP reversal sign](evolution_xero_deleted_payment_sweep.md) — deletions lost when high-water (lastPaymentSync) passes them (sweep/GUID fix recover); AND addPayment subtracted instead of added on AP reversals → negative bill balance; AP balance is incremental (retention-safe, NOT recomputed) so corrupted balances need manual reset
- [Ledger filter LEFT JOIN](evolution_ledger_filter_left_join.md) — GL register (ledgersave.php?call=filter) must LEFT JOIN accounts/branches; inner join hid posted lines whose accountid had no chart row (AP payment rows)
- [Deliveries audit open items](deliveries_audit_open_items.md) — runsheet page: CRITICALs (SQLi, auth gate, dup id) + UX fixed/committed 2026-06-15; still OPEN: 3 High bugs (return_delivery_row args :159, $runsheet->id :513, geocode-false JS :542) + optional write=admin tightening
- [Feature = release notes + docs (policy)](feature_release_docs_policy.md) — every feature needs customer release notes (shape to support_releasenotes_add.inc form fields; don't INSERT) + a docs page (see docs_authoring)
- [Session link hostname](session_link_hostname.md) — build in-session browser links on `shane.evolutionerp.com.au` (app host), NOT `shane-vscode.evolutionerp.com.au` (code-server UI) or links won't resolve
- [Plugin security review (4/10, 4-phase)](plugin_security_review.md) — reconstructed audit at `evolution/audits/PLUGIN_SECURITY_REVIEW.md`; Phase 1 done (XSS/SQLi/AuthZ/tenancy), OPEN: WHERE-clause SQLi (O1), row backfill (O3), CSRF (R1)
- [Invoice total reconciliation](evolution_invoice_total_reconciliation.md) — canonical subtotal = round(adjPrice*qty,2); adjPrice must stay 4dp everywhere; invoiceitems.total uses a different FLOAT formula feeding GL/reports — don't realign it
- [Xero validation project](xero_validation_project.md) — pre-sync validation gate; requirements list done at `evolution/audits/XERO_VALIDATION_REQUIREMENTS.md`; fallback bank = getSetting('defaultBankAccount') explicit-then-implicit; checker + cron change pending
- [Picking→staging ledger model](evolution_picking_staging_ledger.md) — picks = SOH-neutral in/out stockmovement pairs; pickingsave.php diffs by record id as qty-deltas, so in-place bin moves (qtydiff=0) were dropped until relocate-in-place fix; invItemPickChanged is dead data
