docs: record known issues, blocked work and unverified areas; untrack agent scratch

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
main
Thomas Joise 19 hours ago
parent 551c9e3d30
commit 12e95e7be4

@ -1,179 +0,0 @@
{
"running": true,
"startedAt": "2026-07-20T16:44:54.772Z",
"workers": {
"map": {
"runCount": 11,
"successCount": 11,
"failureCount": 0,
"averageDurationMs": 8.090909090909092,
"isRunning": false,
"nextRun": "2026-07-20T19:29:55.184Z",
"lastStartedAt": "2026-07-20T19:14:55.176Z",
"lastRun": "2026-07-20T19:14:55.183Z"
},
"audit": {
"runCount": 17,
"successCount": 17,
"failureCount": 0,
"averageDurationMs": 8.882352941176471,
"isRunning": false,
"nextRun": "2026-07-20T19:26:56.025Z",
"lastStartedAt": "2026-07-20T19:26:56.097Z",
"lastRun": "2026-07-20T19:26:56.134Z"
},
"optimize": {
"runCount": 11,
"successCount": 11,
"failureCount": 0,
"averageDurationMs": 6.454545454545454,
"isRunning": false,
"nextRun": "2026-07-20T19:33:55.170Z",
"lastStartedAt": "2026-07-20T19:18:55.161Z",
"lastRun": "2026-07-20T19:18:55.166Z"
},
"consolidate": {
"runCount": 6,
"successCount": 6,
"failureCount": 0,
"averageDurationMs": 7.5,
"isRunning": false,
"nextRun": "2026-07-20T19:50:55.096Z",
"lastStartedAt": "2026-07-20T19:20:55.092Z",
"lastRun": "2026-07-20T19:20:55.094Z"
},
"testgaps": {
"runCount": 8,
"successCount": 8,
"failureCount": 0,
"averageDurationMs": 8.375,
"isRunning": false,
"nextRun": "2026-07-20T19:32:55.117Z",
"lastStartedAt": "2026-07-20T19:12:55.104Z",
"lastRun": "2026-07-20T19:12:55.114Z"
},
"backup": {
"runCount": 1,
"successCount": 1,
"failureCount": 0,
"averageDurationMs": 9,
"isRunning": false,
"nextRun": "2026-07-21T16:54:54.808Z",
"lastStartedAt": "2026-07-20T16:54:54.797Z",
"lastRun": "2026-07-20T16:54:54.806Z"
},
"harness": {
"runCount": 1,
"successCount": 1,
"failureCount": 0,
"averageDurationMs": 729,
"isRunning": false,
"nextRun": "2026-07-20T22:56:55.533Z",
"lastStartedAt": "2026-07-20T16:56:54.797Z",
"lastRun": "2026-07-20T16:56:55.526Z"
},
"predict": {
"runCount": 0,
"successCount": 0,
"failureCount": 0,
"averageDurationMs": 0,
"isRunning": false
},
"document": {
"runCount": 0,
"successCount": 0,
"failureCount": 0,
"averageDurationMs": 0,
"isRunning": false
}
},
"config": {
"autoStart": false,
"logDir": "C:\\SiMS\\hq\\.claude-flow\\logs",
"stateFile": "C:\\SiMS\\hq\\.claude-flow\\daemon-state.json",
"maxConcurrent": 2,
"workerTimeoutMs": 960000,
"resourceThresholds": {
"maxCpuLoad": 9.600000000000001,
"minFreeMemoryPercent": 10
},
"ttlMs": 43200000,
"idleShutdownMs": 0,
"aiWorkersEnabled": false,
"workers": [
{
"type": "map",
"intervalMs": 900000,
"offsetMs": 0,
"priority": "normal",
"description": "Codebase mapping",
"enabled": true
},
{
"type": "audit",
"intervalMs": 600000,
"offsetMs": 120000,
"priority": "critical",
"description": "Security analysis",
"enabled": true
},
{
"type": "optimize",
"intervalMs": 900000,
"offsetMs": 240000,
"priority": "high",
"description": "Performance optimization",
"enabled": true
},
{
"type": "consolidate",
"intervalMs": 1800000,
"offsetMs": 360000,
"priority": "low",
"description": "Memory distillation (ADR-174)",
"enabled": true
},
{
"type": "testgaps",
"intervalMs": 1200000,
"offsetMs": 480000,
"priority": "normal",
"description": "Test coverage analysis",
"enabled": true
},
{
"type": "backup",
"intervalMs": 86400000,
"offsetMs": 600000,
"priority": "low",
"description": "Nightly memory DB backup (WAL-safe, rotated)",
"enabled": true
},
{
"type": "harness",
"intervalMs": 21600000,
"offsetMs": 720000,
"priority": "low",
"description": "Self-optimizing harness loop (opt-in RUFLO_HARNESS_LOOP, $0-default)",
"enabled": true
},
{
"type": "predict",
"intervalMs": 600000,
"offsetMs": 0,
"priority": "low",
"description": "Predictive preloading",
"enabled": false
},
{
"type": "document",
"intervalMs": 3600000,
"offsetMs": 0,
"priority": "low",
"description": "Auto-documentation",
"enabled": false
}
]
},
"savedAt": "2026-07-20T19:26:56.135Z"
}

@ -1,11 +0,0 @@
{
"timestamp": "2026-07-20T19:14:55.182Z",
"projectRoot": "C:\\SiMS\\hq",
"structure": {
"hasPackageJson": true,
"hasTsConfig": true,
"hasClaudeConfig": true,
"hasClaudeFlow": true
},
"scannedAt": 1784574895183
}

@ -1,16 +0,0 @@
{
"timestamp": "2026-07-20T19:20:55.094Z",
"distillationEnabled": true,
"patternsConsolidated": 0,
"memoryCleaned": 0,
"duplicatesRemoved": 0,
"episodes": 0,
"patternEmbeddings": 0,
"causalEdges": 0,
"promoted": 0,
"byProvenance": {},
"namespaces": [],
"dryRun": false,
"corrupt": false,
"skipped": "no-db"
}

@ -1,17 +0,0 @@
{
"timestamp": "2026-07-20T19:18:55.166Z",
"mode": "local",
"memoryUsage": {
"rss": 46977024,
"heapTotal": 21909504,
"heapUsed": 20452192,
"external": 3903735,
"arrayBuffers": 100670
},
"uptime": 9240.595012,
"optimizations": {
"cacheHitRate": 0.78,
"avgResponseTime": 45
},
"note": "Install Claude Code CLI for AI-powered optimization suggestions"
}

@ -1,12 +0,0 @@
{
"timestamp": "2026-07-20T19:26:56.127Z",
"mode": "local",
"checks": {
"envFilesProtected": true,
"gitIgnoreExists": true,
"noHardcodedSecrets": true
},
"riskLevel": "low",
"recommendations": [],
"note": "Install Claude Code CLI for AI-powered security analysis"
}

@ -1,8 +0,0 @@
{
"timestamp": "2026-07-20T19:12:55.112Z",
"mode": "local",
"hasTestDir": false,
"estimatedCoverage": "unknown",
"gaps": [],
"note": "Install Claude Code CLI for AI-powered test gap analysis"
}

4
.gitignore vendored

@ -25,3 +25,7 @@ ruvector.db
# Database backups (D33) — contain plaintext credentials (D32); never commit
backups/
# agent scratch (claude-flow daemon state/metrics)
.claude-flow/
.claude/

@ -0,0 +1,120 @@
# Known issues & pending work — HQ Ops Console
_Last updated: 2026-07-21 · after the D38 Client Detail redesign landed on `main`._
This is the honest list of what is **not** done, what is **not** verified, and what needs a human
decision. Everything here was found by review; none of it is speculative. Ordered by consequence.
---
## 1. SECURITY — production Postgres password is in the repo and on the remote
**Status: open. Owner decision parked.**
The production Postgres connection string (with password) is hardcoded in
`apps/hq/src/db-pg.ts` (`HARDCODED_DATABASE_URL`), and it **is present on the `origin` remote**
(`gitea.simssoftware.in`). It was introduced in commit `45cfb83` (then in `server.ts`) and later moved
into `db-pg.ts`; both states have been pushed. A duplicate copy that had been added to
`apps/hq/test/db-resolve.test.ts` was removed in `6f50799`.
**Why it matters:** under D31/D32 every client portal/gateway password, module secret and client DB
password is stored **in the clear**. This one credential is therefore the key to all of them.
**The only real remediation is to ROTATE the Postgres password on the box.** Editing or reverting the
file does not remove it from history, and history is already distributed.
Secondary (after rotation), pick one:
- move the value to a deploy-time env var / secrets file and revert the code to a placeholder —
**note the AWS box currently has no `.env`, so this requires an ops change there first**; or
- accept the hardcoded pattern and treat repo read access as equivalent to production DB access.
---
## 2. BLOCKED — the real data has not been touched yet
**Status: blocked on the local Postgres password.**
The following were prepared and tested but **never run against the real database**, because the
local PostgreSQL 17 instance's credentials are not available to this session:
- **Scrub of the "tecnostac" name from the real DB.** The earlier scrub ran against
`data/hq.db` — a near-empty leftover SQLite file (2 clients), **not** the live Postgres. The live
database very likely still contains the old company name, owner login and audit snapshots.
- **The onboarding template migration** over ~167 real projects
(`apps/hq/scripts/apply-onboarding-pipeline.ts`).
- **Redeploy** — the server currently running on `:5182` predates all of this work, so the console
in use does not yet reflect the redesign.
Until this runs, the redesign is **code-complete but not live**.
---
## 3. NOT VERIFIED — things nobody has actually observed working
- **The Postgres migrations have never been executed against a real Postgres instance.**
Migrations `015``018` (`project_milestone.payment_id`, `.document_id`, `ticket.type`,
`client_module.created_at`) are statically reviewed and mirrored from the SQLite schema, but the
test suite's Postgres path is skipped without `HQ_PG_TEST_URL`. 5 tests are skipped for this reason.
- **The Payments tab was not screenshotted at 768px, nor at 1440px in dark theme.** The rest of the
redesign was verified in a real browser at 375 / 768 / 1440 × light + dark.
---
## 4. DEFERRED TO ROADMAP (owner call)
- **`gmail-connect.ts` and the APEX importer CLI use an unconditional `openDb()`** and therefore can
never reach Postgres — they will always target SQLite. `gmail-connect.ts` is a documented production
runbook step. Deferred because that area is not in active use yet.
---
## 5. BEHAVIOUR CHANGES worth knowing
- **Tables now scroll inside their own box, bounded at `70vh`, with a sticky header.** Previously the
whole page scrolled and (at desktop widths) tables silently dropped their rightmost columns. Short
tables are unchanged; long tables scroll internally. This affects every table screen.
- **Adding a module no longer asks for credentials.** They are captured when the "Account creation"
onboarding step is ticked, and remain editable from the module's Access panel.
- **The coarse module status is now driven by the status line.** Ticking Installation / Training /
Go-live advances it automatically; it never downgrades.
---
## 6. MINOR BACKLOG (real, non-blocking)
From the review passes, not yet fixed:
- `bulkSetMilestone` couples to a literal error string (`'Milestone not found on this project'`);
rewording that throw would turn a skip into a whole-batch abort. Prefer a sentinel/typed error.
- `project.stall_days` (the setting, as opposed to the `?days=` query param) is not range-validated;
an absurd value produces a 400 rather than a crash, but it should be clamped for symmetry.
- Whitespace-only `?days=` input is treated as `0` rather than rejected.
- Two `/client-modules/:id/milestones` handlers `await` outside their `try` block (not reachable with
attacker-controlled input, and not a regression).
- `DraftInput.source` is a free-form string taken from the request body — any authenticated user can
tag a document `module_renewal` or `bulk_sms_topup`. Provenance label only, no money impact; a union
type would give a compile-time guard.
- `ClientDetail` still calls `getModules` / `getTicketTypes` on load in some paths; only the duplicate
fetch was removed.
- Chip/button tap targets are ~23px high on mobile — below the comfortable minimum, but this is a
pre-existing system-wide convention, not something this work introduced.
---
## 7. REPO HYGIENE
- **`.claude-flow/` is tracked in git** (6 files of agent daemon state/metrics). It is scratch and
should be removed from tracking and added to `.gitignore`.
- `apps/hq/scripts/migrate-sqlite-to-pg.ts` and `migrate-pg-to-pg.ts` are untracked working files.
- `apps/hq/schema.sql` is a stale generated snapshot (dated 2026-07-10) that no longer matches
`db.ts`, which is the source of truth. It does not even contain `project_milestone`.
---
## How this list was produced
The redesign went through per-task reviews during the build, then a whole-branch review, a four-lens
audit swarm, a real-browser responsive red-team, and a review of the fix commits themselves. Each
layer found defects the previous one could not — including a payment feature that was dead code, a
deploy script that would have written to a phantom database while reporting success, and a route any
authenticated user could crash the server with. Those are fixed. The items above are what remains.
Loading…
Cancel
Save