Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add Cloud Agent dev environment + fix fresh-DB and Postgres import blockers #1378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Add Cloud Agent dev environment + fix fresh-DB and Postgres import blockers #1378
Changes from all commits
dd23ca8d8ef79b4069017File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2 — Cloud Agent install uses unhashed
pip install -r requirements.txt. CI and the Dockerfile require--require-hashes -r requirements-hashes.txt. This weakens the baked environment supply chain.Fix:
python -m pip install --require-hashes -r requirements-hashes.txt(already on #1381).Verify:
pytest tests/test_cloud_agent_environment.py::test_install_sh_pins_python_requirements_with_hashes -qThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2 —
pg_ctlcluster ... || trueplus a 30s wait with no failure lets start continue intoALTER/migrate_db.pywhen Postgres never becomes ready. Fail closed after the wait (pg_isreadyelseexit 1). #1381 adds that guard.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
PostgreSQL psql documentation: verify that--set=name=valuewith:'name'safely substitutes a SQL string literal in a-ccommand.💡 Result:
The use of --set (or -v) variable substitution within the --command (-c) flag of psql is not supported and will not work as expected [1][2][3]. The -c option requires the command string to be completely parsable by the PostgreSQL server, meaning it cannot contain psql-specific features like variable substitution (:name or:'name') [3]. Regarding the safety of:'name' for SQL string literals: while:'name' performs client-side substitution by wrapping the variable's value in single quotes and escaping it, this is a psql-specific feature that only operates during script or standard input processing [1][2][4]. Because -c does not trigger this substitution mechanism, attempting to use:name or:'name' inside -c will result in a syntax error from the database server [2][3]. To use variable substitution safely: 1. Do not use the -c option. 2. Instead, pipe the command into psql (e.g., using echo or a heredoc) or use the -f option to read from a file [1][2][4]. 3. Use the:'name' syntax within your SQL script or piped command to ensure the value is correctly quoted and escaped for use as a SQL string literal [4]. Example of the safe, recommended pattern: psql -v myvar="safe_value" <<< "SELECT * FROM my_table WHERE col =:'myvar';" [4]
Citations:
🌐 Web query:
site:postgresql.org/docs/current/app-psql.html psql -c variable substitution --set :'name'💡 Result:
In psql, the colon (:) prefix is used for variable interpolation, not for defining variables [1]. When you use the --set flag on the command line (e.g., psql --set=name=value), you are assigning a value to a variable named name [1]. You do not include the colon in the variable name when defining it via --set. Once defined, you use the colon to substitute the variable's value within your SQL queries or psql commands. For example: 1. Define the variable on the command line: psql --set=my_var='Hello' 2. Use the variable inside psql: SELECT:'my_var'; The colon instructs psql to replace:my_var with the value of the variable my_var. The syntax:'variable_name' is specifically used to interpolate the variable's value suitably quoted as a string literal, which helps prevent SQL injection and handles special characters safely [1]. If you use the syntax:name (without quotes), psql performs a simple substitution of the variable's value. If you use:'name', psql treats the result as a SQL string literal [1]. The documentation also supports the form:"name" for identifier quoting.
Citations:
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 18208
🌐 Web query:
site:postgresql.org/docs/current/app-psql.html "-c command" "variable substitution" psql💡 Result:
The current PostgreSQL
psqldocumentation states:-c commandaccepts either a server-parsable SQL string or one psql backslash command; SQL and meta-commands cannot be mixed in a single-cargument.:variable,:'variable', and:"variable".-coptions when combining them:[1] (postgresql.org)
Citations:
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 201
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 7180
Reject invalid passwords and use
psqlvariable binding.If
$HOME/.envlacksDATABASE_URLor contains an empty password, the script sets thepostgresrole password to an empty value. Reject a missing or empty password before runningALTER USER.A single quote in
DB_PASSWORDcan terminate the interpolated SQL literal and inject SQL executed aspostgres. Use--set=db_password="$DB_PASSWORD"and:'db_password'instead.🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1 —
ALTER USER postgres WITH PASSWORD '${DB_PASSWORD}'interpolates the role secret into SQL and leaves it on thepsql -cargv. First-boottoken_urlsafeis quote-safe; a pre-existing~/.env(the same filenaruon_compose.shprefers) is not. Empty passwords also proceed.psql -cdoes not expand:'var'(PostgreSQL Global Development Group, n.d., psql). Pass the secret on stdin as dollar-quoted SQL, reject an empty secret, and keep it off argv. #1381 does this inscripts/reconcile_local_postgres_role.py.Verify:
pytest tests/test_reconcile_local_postgres_role.py tests/test_cloud_agent_environment.py -qThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Preserve pre-existing
emails.is_readduring downgrade.Line 28 and Line 29 allow
upgrade()to skip a column that already exists. Lines 46 through 48 then drop any presentis_readcolumn, including one that this revision did not create. A rollback can remove read-state data from a legacy database.Make column ownership explicit, or make this retired-table reconciliation downgrade a safe no-op. Do not infer ownership from current column presence.
🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2 — Downgrade drops
emails.is_readwhenever the column is present, including when this revision skipped upgrade because the column already existed. Make downgrade a documented no-op for the retired table. #1381 does that.This revision still never mutates
email_records. Add a guarded follow-up revision (0018on #1381) foremail_records.is_read NOT NULL DEFAULT true.Verify:
pytest tests/test_alembic_migrations.py::test_email_read_state_revision_is_retired_emails_table_only tests/test_alembic_migrations.py::test_email_record_read_state_revision_guards_canonical_table -qThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 41927
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 50382
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 50382
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 50382
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 50382
🏁 Script executed:
Repository: ContextualWisdomLab/naruon
Length of output: 13184
Add an Alembic migration for
email_records.is_read.No migration creates or alters
email_records.is_read:0011_email_read_stateonly targetsemails, and0014_merge_email_read_stateis a no-op. Existing databases can therefore retainNOT NULLwithoutDEFAULT true, causing raw inserts that omitis_readto fail. Add a guarded migration and a focused existing-schema insert test.🤖 Prompt for AI Agents
Source: Coding guidelines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Use an independent expected value for the lock-key contract.
expected_owner_keyis computed with_owner_import_quota_lock_key, the same helper used by the production request. The assertions therefore prove only that the request path calls the helper and that its output contains no NUL. They do not detect a wrong delimiter, omitted owner component, or changed hash algorithm. Add a focused helper test with a fixed known digest or an independently implemented reference, and keep these endpoint assertions for acquire/release parameter wiring.As per coding guidelines,
backend/tests/**/*requires focused contract tests for changed behavior.Also applies to: 1281-1292, 1348-1357
🤖 Prompt for AI Agents
Source: Coding guidelines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3 — The expected lock key is derived from the production helper, so a rewrite of
_owner_import_quota_lock_keycannot fail this test. Keep the route-wiring asserts, and add an independenthashlib.sha256(b"testuser\\x00org-acme").hexdigest()golden (3fbc5671f32a1608f88c1775c1008c26c53faaea0308b97c556eeceb2b4bb8d3). #1381 addstests/test_email_import_quota_lock_key.py.Uh oh!
There was an error while loading. Please reload this page.