Merge wilm: endpoints plugin, agent, policies, CSV import, Entra fields
Thirteen commits from benjamin.baker plus the review fixes. Everything he built is here: the endpoints plugin and its command queue, the .NET endpoint agent, the computers policies subsystem, the site-asset CSV import with its adapters and collector, Entra device identity, and the catalog hand-merge. His branch predates four commits on main (section ticking, the generator share links, Secure Send copy message, and the smoke-test workflow), so those come through untouched - nothing of ours is removed by this merge. wilm stays as its own branch; this does not close it.
This commit is contained in:
86
.github/agent-workflow.md
vendored
Normal file
86
.github/agent-workflow.md
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
# Agent workflow rules
|
||||
|
||||
Companion to `copilot-instructions.md` (which owns naming/style/architecture).
|
||||
These cut wasted turns. All are lessons from real sessions.
|
||||
|
||||
## Environment - know these, do not rediscover
|
||||
|
||||
- Shell is **PowerShell**: use `;` not `&&`, `2>$null` not `2>/dev/null`.
|
||||
- API container `shopdb-flask-wilm-api-1` (Flask, port `5001`).
|
||||
- DB container `shopdb-flask-wilm-db-1` (MySQL 8, root pw `root_password_123`).
|
||||
- SPA is **baked into the image** (not bind-mounted). Plugin code is
|
||||
**bind-mounted read-only**.
|
||||
- `docs/` is stripped to a public wiki mirror - keep working docs out of it.
|
||||
- `requirements.txt` is hash-checked - never hand-edit.
|
||||
|
||||
## Verify, don't react
|
||||
|
||||
- The terminal "Command failed" banner fires on any non-zero exit or stderr
|
||||
output and is **usually a false negative** (`curl --fail` on a 400,
|
||||
pytest/npm/git writing to stderr). Judge success from real output.
|
||||
- Read container health via
|
||||
`docker inspect --format '{{.State.Health.Status}}'` plus a probe **without**
|
||||
`--fail` - never eyeball the exit code.
|
||||
|
||||
## Container runs the image, not your edits
|
||||
|
||||
Before running anything in the container that must reflect a change:
|
||||
|
||||
1. Frontend: `npm run build`, then
|
||||
`docker cp frontend/dist/. shopdb-flask-wilm-api-1:/app/frontend/dist`.
|
||||
2. Backend/scripts/templates: `docker cp` the files (or rebuild) first.
|
||||
|
||||
If a result contradicts a change you just made, suspect stale container code
|
||||
before re-deriving the fix.
|
||||
|
||||
## Testing
|
||||
|
||||
- Confirm the working directory once, up front.
|
||||
- Run the smallest test that proves the point; find the minimal polluter for
|
||||
isolation bugs. Run the full suite only at the end.
|
||||
- Clear stale local state before plugin/migration tests:
|
||||
`if (Test-Path instance/plugins.json) { Remove-Item instance/plugins.json -Force }`.
|
||||
- Naming-gate hits inside local venvs (`.ci-venv/`, `env/`) are not repo code -
|
||||
do not "fix" vendored libraries.
|
||||
- Final gates, exactly as CI: `python -m pytest tests/ -q`;
|
||||
`cd frontend; npx vitest run; npm run build; cd ..`;
|
||||
`bash scripts/check-naming-and-style.sh`.
|
||||
|
||||
## Migrations and imports
|
||||
|
||||
- Every migration: idempotent guard + real downgrade; must run clean on strict
|
||||
MySQL 8. If you rename indexes in `upgrade()`, update `downgrade()` to match.
|
||||
- Avoid duplicate indexes: `index=True` plus an explicit `db.Index` on the same
|
||||
column creates two.
|
||||
- Importers/seeders match by natural key and must be idempotent - prove it by
|
||||
running twice (expect `updated`, not `created`). Watch all-or-nothing writes.
|
||||
|
||||
## Don't offer rollbacks you don't need
|
||||
|
||||
State current state plainly; surface a rollback path only for a real regression.
|
||||
|
||||
## Wilmington (wilm) local-run known failures - do not re-investigate
|
||||
|
||||
Running the full `python -m pytest tests/ -q` on a Windows dev box (not CI)
|
||||
produces a stable set of environmental failures that are NOT code regressions.
|
||||
Treat these as expected locally; judge your change against CI/Linux instead:
|
||||
|
||||
- `test_core/test_security_headers.py::test_a_served_upload_is_sandboxed` -
|
||||
`PermissionError [WinError 32]` (served upload file still locked by another
|
||||
process). Windows file-lock timing, not a headers bug.
|
||||
- `test_plugin_contract.py::test_import_scan_covers_symlinked_plugins` -
|
||||
`OSError [WinError 1314]` (symlink privilege not held). Needs admin/Developer
|
||||
Mode to create symlinks; irrelevant to plugin logic.
|
||||
- `test_plugin_importguard.py::test_verified_source_signed_ok_tampered_raises` -
|
||||
CRLF vs LF (`b'# plugin\r\n' == b'# plugin\n'`). Git autocrlf checkout, not a
|
||||
signing bug.
|
||||
- `test_docs_publishable.py` and `test_docs_versions.py` - the local `docs/`
|
||||
tree is not the stripped public wiki mirror, so doc-count / PROJECT-MAP
|
||||
assertions fail. Expected off-CI.
|
||||
- `test_core/test_public_read_surface.py::test_every_get_route_is_gated_or_named_public`
|
||||
- pre-existing ungated-GET inventory drift; only act on it if YOUR change
|
||||
added a new GET route.
|
||||
|
||||
If a run shows ONLY these, the suite is green for our purposes. Anything outside
|
||||
this list is real - investigate it.
|
||||
|
||||
1
.github/copilot-instructions.md
vendored
1
.github/copilot-instructions.md
vendored
@@ -72,6 +72,7 @@ name. Spell out: `config context manager request response environment utilities`
|
||||
with quantities are standalone tables, not assets.
|
||||
- **Ledger pattern**: a cached `quantityonhand` moves in the SAME commit as the
|
||||
signed transaction row it reflects.
|
||||
- **Configuration for endpoint agent**: The endpoint agent's live collector key and base URL are provisioned in the Windows registry `HKLM\SOFTWARE\GE\ShopDB` (values `CollectorKey`, `BaseUrl`), not committed in `appsettings.json`; `appsettings.json` holds only non-secret runtime settings.
|
||||
|
||||
## Before you finish a change
|
||||
|
||||
|
||||
Reference in New Issue
Block a user