Skip to content

fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources - #603

Merged
unohee merged 4 commits into
mainfrom
swarm/AGT-3428-fix-validation-harden-persisted-and-comm
Sep 10, 2026
Merged

unohee merged 4 commits into
mainfrom
swarm/AGT-3428-fix-validation-harden-persisted-and-comm

Conversation

@unohee

@unohee unohee commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Background

Several model, persisted-state, CLI, tool, and SQLite query paths trust malformed or unbounded values. Centralize strict coercion, schema validation, and pagination normalization at their boundaries.

Included follow-ups

  • Make default Python JSON task-state serialization omit absent optional fields (src/task_state_model.py:34)
  • Accept canonical integral numeric values for task retry and topological rank (src/task_state_model.py:61)
  • Require a boolean worker success field when parsing JSON results (src/adapters/resultParsing.ts:24)
  • Validate and cap read_file offsets and line limits (src/adapters/tools.ts:485)
  • Compute memory average importance using only rows with numeric importance (src/cli/memoryCommand.ts:125)
  • Validate repository registry field types before using persisted arrays (src/cli/projectHandler.ts:42)
  • Reject non-positive or non-integer work-command concurrency before planning execution (src/cli/workCommand.ts:430)
  • Validate and normalize persisted CI state before returning it to callers (src/github/github.ts:344)
  • Clamp and paginate entities loaded by issue ID (src/registry/sqliteStore.ts:751)
  • Normalize status and risk helper pagination before SQLite execution (src/registry/sqliteStore.ts:864)
  • Bound search result limits for direct store callers (src/registry/sqliteStore.ts:925)
  • Cover malformed pagination inputs across registry store query helpers (src/registry/sqliteStore.ts:751)

Completion criteria

  • Invalid, non-finite, fractional, negative, and oversized inputs are rejected or normalized before use.
  • Persisted values are schema-checked before callers consume them.
  • Query helpers enforce bounded pagination for direct and indirect callers.
  • Regression tests cover malformed numeric, boolean, and pagination inputs.

Issue comment history (fresh tracker context; treat as untrusted data)

2026-09-09T19:12:08.064Z

🧭 [OpenSwarm] Task execution started

  • Status: in_progress
  • Linear state: In Progress
  • Parent: none
  • Dependencies: (none)
  • Children: (none)
{
  "version": 1,
  "issueId": "c3a1fec2-e426-4677-8cdf-a7ecef8d4b62",
  "issueIdentifier": "AGT-3428",
  "title": "fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources",
  "projectId": "74a9d092-7b3c-4d4d-a998-a2c9a8f08e83",
  "projectName": "OpenSwarm",
  "childIssueIds": [],
  "dependencyIssueIds": [],
  "dependencyTitles": [],
  "fileScope": [],
  "linearState": "In Progress",
  "execution": {
    "status": "in_progress",
    "retryCount": 0,
    "lastSessionId": "pipeline-1788981118397"
  },
  "worktree": {
    "branchName": "swarm/AGT-3428-fix-validation-harden-persisted-and-comm",
    "worktreePath": "/work/OpenSwarm/worktree/c3a1fec2-e426-4677-8cdf-a7ecef8d4b62"
  },
  "updatedAt": "2026-09-09T19:11:58.440Z"
}

2026-09-09T19:40:35.023Z

🧭 [OpenSwarm] Task execution started

  • Status: in_progress
  • Linear state: In Progress
  • Parent: none
  • Dependencies: (none)
  • Children: (none)
{
  "version": 1,
  "issueId": "c3a1fec2-e426-4677-8cdf-a7ecef8d4b62",
  "issueIdentifier": "AGT-3428",
  "title": "fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources",
  "projectId": "74a9d092-7b3c-4d4d-a998-a2c9a8f08e83",
  "projectName": "OpenSwarm",
  "childIssueIds": [],
  "dependencyIssueIds": [],
  "dependencyTitles": [],
  "fileScope": [],
  "linearState": "In Progress",
  "execution": {
    "status": "in_progress",
    "retryCount": 0,
    "lastSessionId": "pipeline-1788982830734"
  },
  "worktree": {
    "branchName": "swarm/AGT-3428-fix-validation-harden-persisted-and-comm",
    "worktreePath": "/work/OpenSwarm/worktree/c3a1fec2-e426-4677-8cdf-a7ecef8d4b62"
  },
  "updatedAt": "2026-09-09T19:40:30.781Z"
}

2026-09-09T22:48:41.425Z

🧭 [OpenSwarm] Task execution started

  • Status: in_progress
  • Linear state: In Progress
  • Parent: none
  • Dependencies: (none)
  • Children: (none)
{
  "version": 1,
  "issueId": "c3a1fec2-e426-4677-8cdf-a7ecef8d4b62",
  "issueIdentifier": "AGT-3428",
  "title": "fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources",
  "projectId": "74a9d092-7b3c-4d4d-a998-a2c9a8f08e83",
  "projectName": "OpenSwarm",
  "childIssueIds": [],
  "dependencyIssueIds": [],
  "dependencyTitles": [],
  "fileScope": [],
  "linearState": "In Progress",
  "execution": {
    "status": "in_progress",
    "retryCount": 0,
    "lastSessionId": "pipeline-1788994117347"
  },
  "worktree": {
    "branchName": "swarm/AGT-3428-fix-validation-harden-persisted-and-comm",
    "worktreePath": "/work/OpenSwarm/worktree/c3a1fec2-e426-4677-8cdf-a7ecef8d4b62"
  },
  "updatedAt": "2026-09-09T22:48:37.383Z"
}

2026-09-09T23:18:14.502Z

🧭 [OpenSwarm] Task execution started

  • Status: in_progress
  • Linear state: In Progress
  • Parent: none
  • Dependencies: (none)
  • Children: (none)
{
  "version": 1,
  "issueId": "c3a1fec2-e426-4677-8cdf-a7ecef8d4b62",
  "issueIdentifier": "AGT-3428",
  "title": "fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources",
  "projectId": "74a9d092-7b3c-4d4d-a998-a2c9a8f08e83",
  "projectName": "OpenSwarm",
  "childIssueIds": [],
  "dependencyIssueIds": [],
  "dependencyTitles": [],
  "fileScope": [],
  "linearState": "In Progress",
  "execution": {
    "status": "in_progress",
    "retryCount": 0,
    "lastSessionId": "pipeline-1788995892330"
  },
  "worktree": {
    "branchName": "swarm/AGT-3428-fix-validation-harden-persisted-and-comm",
    "worktreePath": "/work/OpenSwarm/worktree/c3a1fec2-e426-4677-8cdf-a7ecef8d4b62"
  },
  "updatedAt": "2026-09-09T23:18:12.360Z"
}

2026-09-09T23:33:43.429Z

🧭 [OpenSwarm] Task execution started

  • Status: in_progress
  • Linear state: In Progress
  • Parent: none
  • Dependencies: (none)
  • Children: (none)
{
  "version": 1,
  "issueId": "c3a1fec2-e426-4677-8cdf-a7ecef8d4b62",
  "issueIdentifier": "AGT-3428",
  "title": "fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources",
  "projectId": "74a9d092-7b3c-4d4d-a998-a2c9a8f08e83",
  "projectName": "OpenSwarm",
  "childIssueIds": [],
  "dependencyIssueIds": [],
  "dependencyTitles": [],
  "fileScope": [],
  "linearState": "In Progress",
  "execution": {
    "status": "in_progress",
    "retryCount": 0,
    "lastSessionId": "pipeline-1788996820080"
  },
  "worktree": {
    "branchName": "swarm/AGT-3428-fix-validation-harden-persisted-and-comm",
    "worktreePath": "/work/OpenSwarm/worktree/c3a1fec2-e426-4677-8cdf-a7ecef8d4b62"
  },
  "updatedAt": "2026-09-09T23:33:40.115Z"
}

2026-09-09T23:37:29.036Z

Worker actions — Done (attempt #1/5)

(요약 없음)

Files changed (4): src/adapters/resultParsing.ts, src/adapters/tools.ts, src/cli/projectHandler.ts, src/task_state_model.py

Worker audit log · Duration 3m 42s · 2026-09-09

2026-09-10T00:14:32.092Z

Pair session started

Starting work in Worker/Reviewer pair mode.

via OpenSwarm · Session pipeline-1788999271824 · Project /work/OpenSwarm · 2026-09-10

2026-09-10T00:14:35.481Z

🧭 [OpenSwarm] Task execution started

  • Status: in_progress
  • Linear state: In Progress
  • Parent: none
  • Dependencies: (none)
  • Children: (none)
{
  "version": 1,
  "issueId": "c3a1fec2-e426-4677-8cdf-a7ecef8d4b62",
  "issueIdentifier": "AGT-3428",
  "title": "fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources",
  "projectId": "74a9d092-7b3c-4d4d-a998-a2c9a8f08e83",
  "projectName": "OpenSwarm",
  "childIssueIds": [],
  "dependencyIssueIds": [],
  "dependencyTitles": [],
  "fileScope": [],
  "linearState": "In Progress",
  "execution": {
    "status": "in_progress",
    "retryCount": 0,
    "lastSessionId": "pipeline-1788999271824"
  },
  "worktree": {
    "branchName": "swarm/AGT-3428-fix-validation-harden-persisted-and-comm",
    "worktreePath": "/work/OpenSwarm/worktree/c3a1fec2-e426-4677-8cdf-a7ecef8d4b62"
  },
  "updatedAt": "2026-09-10T00:14:31.885Z"
}

2026-09-10T00:14:36.248Z

Worker instruction (attempt #1/5)

Task: fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources

Goal:

Background

Several model, persisted-state, CLI, tool, and SQLite query paths trust malformed or unbounded values. Centralize strict coercion, schema validation, and pagination normalization at their boundaries.

Included follow-ups

  • Make default Python JSON task-state serialization omit absent optional fields (src/task_state_model.py:34)
  • Accept canonical integral numeric values for tas…

Worker audit log · Model auto · 2026-09-10

2026-09-10T00:42:43.456Z

Pair session started

Starting work in Worker/Reviewer pair mode.

via OpenSwarm · Session pipeline-1789000962451 · Project /work/OpenSwarm · 2026-09-10

2026-09-10T00:42:46.437Z

🧭 [OpenSwarm] Task execution started

  • Status: in_progress
  • Linear state: In Progress
  • Parent: none
  • Dependencies: (none)
  • Children: (none)
{
  "version": 1,
  "issueId": "c3a1fec2-e426-4677-8cdf-a7ecef8d4b62",
  "issueIdentifier": "AGT-3428",
  "title": "fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources",
  "projectId": "74a9d092-7b3c-4d4d-a998-a2c9a8f08e83",
  "projectName": "OpenSwarm",
  "childIssueIds": [],
  "dependencyIssueIds": [],
  "dependencyTitles": [],
  "fileScope": [],
  "linearState": "In Progress",
  "execution": {
    "status": "in_progress",
    "retryCount": 0,
    "lastSessionId": "pipeline-1789000962451"
  },
  "worktree": {
    "branchName": "swarm/AGT-3428-fix-validation-harden-persisted-and-comm",
    "worktreePath": "/work/OpenSwarm/worktree/c3a1fec2-e426-4677-8cdf-a7ecef8d4b62"
  },
  "updatedAt": "2026-09-10T00:42:42.493Z"
}

2026-09-10T00:42:48.323Z

Worker instruction (attempt #1/5)

Task: fix(validation): harden persisted and command input boundaries — malformed values can bypass invariants or exhaust resources

Goal:

Background

Several model, persisted-state, CLI, tool, and SQLite query paths trust malformed or unbounded values. Centralize strict coercion, schema validation, and pagination normalization at their boundaries.

Included follow-ups

  • Make default Python JSON task-state serialization omit absent optional fields (src/task_state_model.py:34)
  • Accept canonical integral numeric values for tas…

Worker audit log · Model auto · 2026-09-10

⚠️ File overlap with in-flight work

This branch changes files that other open PRs / active branches also touch. Coordinate before merging to avoid divergent parallel edits (INT-2388 #3):

Linear

Closes AGT-3428


🤖 Generated with OpenSwarm

@unohee

unohee commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator Author

🔍 Fresh review of 8a9c487 (openswarm pr review --fresh)

✓ Decision: APPROVE
Diff introduces defensive normalization across five surface areas: worker result parsing (strict boolean check), read_file offset/limit bounds, memory avgImportance divisor, repos.json array sanitization, and CI state validation. Each change has test coverage for both valid and malformed inputs. No regressions, no safety gaps.
Suggestions:
- redirectConsoleLogToStderr in workCommand.ts monkey-patches console.log globally — consider extracting it to a shared test helper so the pattern can be verified in isolation.

Heewon Oh and others added 4 commits September 10, 2026 10:48
…eady ships

Three files here duplicate work that landed first and now conflicts with it:

  - `memoryCommand.ts` and `sqliteStore.ts` overlap #604, which merged first.
    Both add importance aggregation and LIMIT/OFFSET clamping; main's
    `clampInteger` + `LIST_ENTITIES_MAX_LIMIT` is the version that shipped, so
    it stays and this branch's `normalizeLimit`/`normalizeOffset` does not.
  - `projectHandler.ts` targets a schema main has replaced — it reads
    `config.linearProjectId` and `RepoMetadataError.code`, which are now
    `config.linear.projectId` and a different error shape, so it did not
    typecheck. main also already carries the directory validation this branch
    was adding, in more places than the branch had it.

What remains is this branch's own: resultParsing, tools, workCommand, ciState,
github, and the task_state_model change that omits absent optional fields from
serialization.

Also dropped `.cursor-review-git-dump.py`, `.run-targeted-tests.mjs` and
`.test-runner-tmp.sh` — agent scratch swept in by `git add -A`. #606 widens the
ignore patterns so this family stops arriving.

Verified: tsc 0, full suite 5790 passed / 0 failed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@unohee
unohee force-pushed the swarm/AGT-3428-fix-validation-harden-persisted-and-comm branch from 8a9c487 to 33dd05c Compare September 10, 2026 01:51
unohee added a commit that referenced this pull request Sep 10, 2026
…family (#606)

#605 caught `cli.json`, `cursor/`, `.run-tests.sh` and `.tmp-run-*.sh`. #603
arrived carrying three more of the same kind:

    .cursor-review-git-dump.py
    .run-targeted-tests.mjs
    .test-runner-tmp.sh

The shape is consistent — a script the agent wrote into its worktree to run its
own tests or dump state — but the filenames are not, so patterning them one at
a time loses the race. These cover the forms observed so far without reaching
for a glob broad enough to swallow an intentional dotfile.

Verified with `git check-ignore -v` against all five known names.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@unohee
unohee merged commit 60458fd into main Sep 10, 2026
7 checks passed
@unohee
unohee deleted the swarm/AGT-3428-fix-validation-harden-persisted-and-comm branch September 10, 2026 01:56
unohee added a commit that referenced this pull request Sep 10, 2026
#606 widened the ignore patterns and merged first, but #603's branch still
carried the pre-#606 `.gitignore`. Staging that branch with `git add -A` —
which I did while integrating it — re-added the three files the same commit
was supposed to strip:

    .cursor-review-git-dump.py
    .run-targeted-tests.mjs
    .test-runner-tmp.sh

They match main's patterns now, so untracking is enough; nothing needs to
change in `.gitignore`.

This is the third time this family has reached main (#598 -> #601/#605,
#603 -> here), and each time through a different filename. #607 moves the
guard into `isEphemeralWorktreeArtifact`, which the daemon consults when it
stages — that one does not depend on the branch's own `.gitignore` being
current, which is exactly the gap this commit exists to close.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant