Skip to content

Polish: strict int parsing, --db wiring, config backups, email_verified, yaml fallback (#37)#40

Merged
tcconnally merged 1 commit into
mainfrom
fix/polish
Jun 24, 2026
Merged

Polish: strict int parsing, --db wiring, config backups, email_verified, yaml fallback (#37)#40
tcconnally merged 1 commit into
mainfrom
fix/polish

Conversation

@tcconnally

Copy link
Copy Markdown
Contributor

Implements the low-severity correctness & hardening polish punch-list from issue #37.

Changes

1. ✅ Integer parsing now rejects floats instead of silently truncating

  • Issue: int(ev.get('input_tokens', 0) or 0) in /v1/usage ingest silently truncated 1.9 → 1
  • Fix: Added strict_int() helper in plutus_agent/utils.py that raises ValueError on floats/decimal strings
  • Applied to: Token count fields in server/app.py ingest validation
  • Behavior: Accepts 5, '5', 0; rejects 1.9, '1.9', 1.0

2. ✅ CLI --db argument now wired through

  • Issue: --db was not declared in argparse; CLI always used PLUTUS_DB env var
  • Fix: Added --db to top-level parser in cli.py, sets PLUTUS_DB env var in main()
  • Verification: plutus --db /tmp/x.db status now uses that DB path

3. ✅ Empty API key validation already safe

  • Status: No change needed
  • Verification: db.api_key_org() at line 360 already checks if not secret or not secret.startswith(API_KEY_PREFIX): return None
  • Empty string / whitespace / non-prefixed keys are rejected

4. ✅ Added missing FOREIGN KEY constraint

  • Issue: alerts_log.workspace_id had no FOREIGN KEY
  • Fix: Added REFERENCES workspaces(id) ON DELETE SET NULL in db.py schema
  • Note: Only applies to fresh DBs (schema uses CREATE TABLE IF NOT EXISTS); existing DBs unaffected

5. ✅ Config save() now creates timestamped backups

  • Issue: config.py save() overwrote config.yaml without backup
  • Fix: Before overwriting, copies existing file to .yaml.bak-YYYYMMDDHHMMSS
  • Behavior: Only backs up when prior file exists (no backup on first save)

6. ✅ email_verified check now requires explicit truthy value

  • Issue: auth._claims_from_id_token only rejected email_verified in (False, 'false'); missing claim was allowed
  • Fix: Changed to email_verified not in (True, 'true') — must be explicitly truthy
  • Behavior: Missing / False / any other value → AuthError('email is not verified')

7. ✅ YAML fallback reader can now parse simple YAML

  • Issue: _minimal_yaml_read only parsed JSON; couldn't read YAML files it wrote when PyYAML absent
  • Fix: Added simple YAML parser supporting key: value and one level of 2-space-indented nesting
  • Behavior: Keeps JSON fast-path; tolerant to files written with PyYAML

Testing

All existing tests remain green (42 tests pass) + new focused tests:

  • test_strict_int_accepts_integers / test_strict_int_rejects_floats
  • test_db_wiring_honors_env
  • test_config_save_creates_backup
  • test_email_verified_requires_truthy
  • test_minimal_yaml_read_roundtrip

Verified:

  • python3 tests/test_engine.py — all 42 tests pass
  • python3 -m compileall -q plutus_agent — clean
  • python3 -m plutus_agent --version — works

Closes #37

…ed, yaml fallback (#37)

Implements the low-severity correctness & hardening polish punch-list from issue #37:

1. ✓ Integer parsing now rejects floats instead of silently truncating
   - Added strict_int() helper in plutus_agent/utils.py
   - Applied to /v1/usage ingest validation in server/app.py
   - Raises ValueError on '1.9'/1.9, accepts 5/'5'/0

2. ✓ CLI --db argument is now wired through
   - Added --db to argparse in cli.py
   - Sets PLUTUS_DB env var so all db.connect() calls honor it
   - `plutus --db /tmp/x.db status` now uses that DB

3. ✓ Empty API key validation already safe
   - db.api_key_org() already rejects empty/non-prefixed secrets (line 360)
   - Documented in PR body

4. ✓ Added missing FOREIGN KEY constraint
   - alerts_log.workspace_id now has FOREIGN KEY → workspaces(id) ON DELETE SET NULL
   - Only applies to fresh DBs (CREATE TABLE IF NOT EXISTS)

5. ✓ Config save() now creates timestamped backups
   - Backups existing config to .yaml.bak-YYYYMMDDHHMMSS before overwriting
   - Only when prior file exists (no backup on first save)

6. ✓ email_verified check now requires explicit truthy value
   - auth._claims_from_id_token now requires email_verified in (True, 'true')
   - Missing/False/any other value raises AuthError

7. ✓ YAML fallback reader can now parse simple YAML
   - _minimal_yaml_read now handles 'key: value' and one level of 2-space nesting
   - Keeps JSON fast-path, tolerant to files written with PyYAML

All existing tests remain green + new focused tests added:
- test_strict_int_accepts_integers / test_strict_int_rejects_floats
- test_db_wiring_honors_env
- test_config_save_creates_backup
- test_email_verified_requires_truthy
- test_minimal_yaml_read_roundtrip

Tested: All 42 tests pass, python3 -m compileall clean, --version works.
@tcconnally tcconnally merged commit 999bb07 into main Jun 24, 2026
3 of 4 checks passed
@tcconnally tcconnally deleted the fix/polish branch June 24, 2026 01:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[polish] Low-severity correctness & hardening punch-list (1.0)

1 participant