Skip to content
5 changes: 5 additions & 0 deletions .agents/sessions/context-baseline-25k/EVENTS.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@
{"ts":"2026-08-05T02:59:40.287Z","kind":"append_lesson","summary":"Appended entry \"Deliverables committed — 2026-08-05\" to STATUS.md","payload":{"heading":"Deliverables committed — 2026-08-05","artifact":"STATUS.md"}}
{"ts":"2026-08-05T06:02:55.271Z","kind":"append_lesson","summary":"Appended entry \"AC-A1 pre-flip smoke baselines — 2026-08-05\" to STATUS.md","payload":{"heading":"AC-A1 pre-flip smoke baselines — 2026-08-05","artifact":"STATUS.md"}}
{"ts":"2026-08-05T10:11:05.320Z","kind":"append_lesson","summary":"Appended entry \"M3 tree/knowledge reductions — 2026-08-05\" to STATUS.md","payload":{"heading":"M3 tree/knowledge reductions — 2026-08-05","artifact":"STATUS.md"}}
{"ts":"2026-08-05T17:37:42.620Z","kind":"append_lesson","summary":"Appended entry \"Resume 2026-08-05 — continue open plan\" to STATUS.md","payload":{"heading":"Resume 2026-08-05 — continue open plan","artifact":"STATUS.md"}}
{"ts":"2026-08-05T17:44:16.775Z","kind":"append_lesson","summary":"Appended entry \"M5-T1 ranking — 2026-08-05\" to STATUS.md","payload":{"heading":"M5-T1 ranking — 2026-08-05","artifact":"STATUS.md"}}
{"ts":"2026-08-05T17:46:34.461Z","kind":"append_lesson","summary":"Appended entry \"M5 schema diet complete — 2026-08-05\" to STATUS.md","payload":{"heading":"M5 schema diet complete — 2026-08-05","artifact":"STATUS.md"}}
{"ts":"2026-08-05T17:59:42.119Z","kind":"append_lesson","summary":"Appended entry \"M5 security review cleared\" to STATUS.md","payload":{"heading":"M5 security review cleared","artifact":"STATUS.md"}}
{"ts":"2026-08-05T17:59:42.119Z","kind":"session_status","summary":"Session status -> validating","payload":{"status":"validating"}}
10 changes: 10 additions & 0 deletions .agents/sessions/context-baseline-25k/STATE.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"schemaVersion": 2,
"slug": "context-baseline-25k",
"status": "validating",
"currentTask": null,
"revision": 1,
"checkpoint": null,
"createdAt": "2026-08-05T17:59:42.119Z",
"updatedAt": "2026-08-05T17:59:42.119Z"
}
58 changes: 58 additions & 0 deletions .agents/sessions/context-baseline-25k/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,61 @@ M3-T1..T4 landed (AC-A1 for M2 already satisfied).
- Default fixed (prod, SMALL, no proactive): **46,808** tok (session-dependent git still inflates)

**Next:** gate this M3 diff; optional commit after GATE: PASSED. M5 schema diet / M1 tool default-on still separate.

<!-- update_plan_status:appended -->
## Resume 2026-08-05 — continue open plan — 2026-08-05T17:37:42.619Z

Resumed context-baseline-25k. Verified live tree:

- M1 canary surface (tool tiers + unlock + locked-tool path + Tool surface prompt): landed earlier; default-on still blocked on AC-A1 for tools (prompt AC-A1 already satisfied for M2).
- M2 progressive prompt disclosure default-on: committed `71eb68b44`.
- M3 cheaper SMALL tree (1750) + knowledge blurb: committed `9ce22c079`.
- M4 lean proactive: committed in `77f403b01` + NF-1/NF-2 follow-ups.

PLAN checkboxes were stale; syncing done markers. Next implementation: **M5 schema/description diet** (rank CORE tools, shorten top descriptions, keep core ≤12k), then M6 history hygiene polish and remaining X-T docs if needed.


<!-- update_plan_status:appended -->
## M5-T1 ranking — 2026-08-05 — 2026-08-05T17:44:16.775Z

Measured via `scripts/rank-core-tool-tokens.ts` (new):

| Metric | Tokens |
|---|---:|
| CORE total | **14,183** |
| progressive core-only | **14,183** |
| full surface (33 tools) | **23,598** |
| AC-F2 core target | ≤12,000 |

Top CORE costs: read_files 3002, spawn_agents 2876, query_index 1219, ask_user 1078, check_job 954, check_background_agent 936, suggest_followups 754, write_todos 627, list_jobs 569, glob 549.

Next: M5-T2 shorten top CORE tool descriptions (~2.5–4k savings needed).


<!-- update_plan_status:appended -->
## M5 schema diet complete — 2026-08-05 — 2026-08-05T17:46:34.460Z

M5-T1 ranking + M5-T2/T3 description diet landed.

**Token budget (scripts/rank-core-tool-tokens.ts):**
| Metric | Before | After |
|---|---:|---:|
| CORE / progressive core-only | 14,183 | **9,680** (AC-F2 ≤12k met) |
| Full surface (33 tools) | 23,598 | **19,095** (≤25k still met) |

**Edits:** shortened model-facing `description` prose on top CORE tools under `common/src/tools/params/tool/` (read_files, spawn_agents, query_index, ask_user, check_job, check_background_agent, suggest_followups, write_todos, list_jobs, glob, read_subtree, read_logs). Ranking helper: `scripts/rank-core-tool-tokens.ts`.

**Validation (local):**
- `bun test` coerce-to-array + base2-progressive-tool-disclosure + base2-context-budget: green (core-only <12k assertion pass)
- `cd common && bun run typecheck`: clean

**M6 quick check:** `tool-result-lifecycle.ts` already tags `query_index` as VERBOSE + normal importance (not pinned/high); spawn tools stay high. M6-T1 largely already satisfied; residual M6-T2/T3 optional polish only.

**Still open on this plan:** M1 tool default-on (AC-A1 for tools), M5 default-on N/A (diet is always-on), optional M6 polish, X-T docs for tool tiers + schema diet.


<!-- update_plan_status:appended -->
## M5 security review cleared — 2026-08-05T17:59:42.118Z

Snapshot-bound security-reviewer returned LOOKS_GOOD (receipt 0xRtSQH7XPo / snapshot v3:8b8a8c283b248aeb571eb42f715cc448ac9d77f39c473a974eb8ecdeb6eb1db5). Coverage covered; no findingIds. Pending files: rank script + 12 CORE tool description diets. Local checks earlier: coreTotal 9680 (≤12k), 138+8 tests pass, common typecheck clean. Ending turn for automated hooks+reviewer gate.

4 changes: 4 additions & 0 deletions .agents/sessions/terminal-policy-repair-2026-08/EVENTS.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{"ts":"2026-08-04T15:19:32.662Z","kind":"append_lesson","summary":"Appended entry \"RF tee findings status\" to STATUS.md","payload":{"heading":"RF tee findings status","artifact":"STATUS.md"}}
{"ts":"2026-08-04T15:19:32.663Z","kind":"session_status","summary":"Session status -> validating","payload":{"status":"validating"}}
{"ts":"2026-08-04T21:04:52.636Z","kind":"append_lesson","summary":"Appended entry \"Session complete — 2026-08-04\" to STATUS.md","payload":{"heading":"Session complete — 2026-08-04","artifact":"STATUS.md"}}
{"ts":"2026-08-04T21:04:52.639Z","kind":"session_status","summary":"Session status -> completed","payload":{"status":"completed"}}
13 changes: 13 additions & 0 deletions .agents/sessions/terminal-policy-repair-2026-08/LESSONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# LESSONS — Terminal policy repair

## Lessons captured during planning
- Segment-parsed safety detectors must fail closed: `segments?.some(unsafe) ?? false` is a fail-open hole whenever the segment splitter returns undefined (background `&`, empty segments from trailing/leading `;`, `;;`). Read-only profile already denies on `!segments`; tmux-test detectors skipped that posture.
- Blanket-bans vs. composition-aware checks: removing the raw-newline ban was correct UX, but every downstream guard that parsed "commands" needed re-auditing for the new separator class. Policy changes that widen the input alphabet must be paired with a fail-open review of all segment consumers.
- Reviewer findings are snapshot-bound and RF-ID-keyed: they cannot be cleared conversationally; each repair edit must cite the finding IDs, and only a fresh matching reviewer pass clears them.
- repair-editor requires the structured `handoff` object, not a bare prompt — a prompt-only spawn failed handler validation.
- Consistency between allow guards and message helpers matters: the allow regex accepted only `-m` while placeholder/strip helpers already handled `--message`/`--message=`, producing a confusing generic deny for a documented form.

## Gotchas for execution
- `splitReadOnlyShellSegments` treats `\r\n` as one separator; any new test with CRLF should account for that.
- Existing positive tmux-test tests (`normalizes tmux executable quoting…`, `applies outside-absolute-path containment…`) are the regression canary for fail-closed changes.
- `\r|\n` multi-line composition under validation-diagnosis is intentionally still fail-closed unless it matches the bounded `cat > file <<'EOF'…EOF` heredoc — do not loosen this while fixing tmux-test.
54 changes: 54 additions & 0 deletions .agents/sessions/terminal-policy-repair-2026-08/PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# PLAN — Terminal policy repair (RF-1..RF-6)

<!-- current-task: T1 -->

Single milestone: close all six reviewer findings, re-validate, pass a fresh reviewer pass.

## Tasks

- [ ] T1 — Inventory fail-open tmux detectors
- Role: editor (read phase) or direct read
- Read `sdk/src/tools/terminal-command-policy.ts` fresh and list every tmux-test detector that consumes `splitReadOnlyShellSegments(command)` with `segments?.some(...) ?? false` or equivalent: `hasUnsafeTmuxFileMutation`, `hasUnsafeTmuxSedInPlace`, `hasUnsafeTmuxExecutable`, `hasUnsafeTmuxGitCommand`, `hasUnsafeTmuxWriteRedirection`, `hasActiveTmuxCompoundShellSyntax`.
- Acceptance: complete list of `?? false`/fail-open sites confirmed against live file, not memory.
- Validate: code-search `segments\?\.` and `?? false` in terminal-command-policy.ts.

- [ ] T2 — Make tmux-test detectors fail closed (RF-1, RF-5)
- Depends on: T1
- For each detector identified in T1, change the unparseable path from `?? false` to `?? true` (undefined segments ⇒ treat composition as unsafe). Do not touch detectors that genuinely don't parse segments. Keep each function's name/signature.
- Rationale to preserve in a brief comment: `splitReadOnlyShellSegments` returns undefined on background `&`, substitution, or empty segments; bash still executes those forms, so tmux-test must deny rather than skip the guard.
- Acceptance: `touch workspace.txt;`, `tee workspace.txt;`, `rm -rf src &`, `touch x;;echo y`, `; touch x` all denied under `tmux-test`.
- Validate: run policy test file (T5 gate) — no new fail-closed false-positives on the existing allow cases in `blocks tmux agents from direct workspace mutation` / `normalizes tmux executable quoting`.

- [ ] T3 — Align git-commit allow with `--message` (RF-3, RF-6)
- Depends on: T2
- Extend the git-commit commit-allow regex from `(?=.*-m(?:\s|$))` to also accept `--message` forms: `(?=.*(?:-m|--message)(?:\s|=|$))`. Keep placeholder-message rejection and non-amend guard unchanged.
- Acceptance: `git commit --message "Fix the parser"` allowed (with real message); `git commit --message probe` still denied as placeholder; `--message="Fix"` allowed.
- Validate: policy tests.

- [ ] T4 — Add failing-closed test cases (RF-2, RF-4, RF-6)
- Depends on: T2, T3
- In `sdk/src/__tests__/terminal-command-policy.test.ts` add:
- a tmux-test test asserting `allowed === false` for trailing `;`, `;;`, leading `;`, and background `&` around `touch`/`tee`/`rm` mutators (e.g. `tmux run-shell 'touch /tmp/x;'` shape if fixtures are wrapped, per existing test idioms — mirror the style of `blocks tmux agents from direct workspace mutation`);
- git-commit allow cases: `git commit --message "Fix the parser"`, `git commit --message="Fix the parser"` → allowed true; placeholder via `--message` → false.
- Acceptance: new tests fail against the pre-T2/T3 code and pass after.
- Validate: run policy test file.

- [ ] T5 — Validate
- Depends on: T4
- Run `bun test sdk/src/__tests__/terminal-command-policy.test.ts` (must be all-pass) and end turn so hooks (`bun run typecheck`, `cd sdk && bun run typecheck`) run.
- Acceptance: 0 failures; hooks green.
- Validate: basher output + gate hooks summary.

- [ ] T6 — Fresh reviewer pass (RF-1..RF-6)
- Depends on: T5
- End turn; harness runs the automated reviewer against the new snapshot. If any finding re-opens, do exactly one targeted repair for that finding ID and re-validate (no broad rewrites).
- Acceptance: GATE: PASSED; all six RF records cleared.

## Execution notes (execute mode)
- Edit through `repair-editor` with the full handoff contract (schemaVersion, taskId, role='repair-editor', objective, requirements[] one per RF ID, acceptanceCriteria[] one per RF ID, context: [], nonGoals, findings[] with files + snapshotFingerprint, permissions{readablePaths, writablePaths, allowedTools}). A previous repair-editor spawn failed validation because only a prose prompt was sent — always include the structured `handoff` object and cite finding IDs (RF-1-4391b95f, RF-2-327c10c4, RF-3-fa741f2a, RF-4-7b925458, RF-5-e9fa653a, RF-6-7a8c09df). Use the full snapshot fingerprint from the harness state at execute time (prefix `v3:7fa30d019b80a…`).
- Sequential discipline: read fresh → one repair transaction → run policy tests → end turn. No parallel reviewer during repair.
- Preserve unrelated dirty work: `scripts/measure-context-baseline.ts`, `agents/base2/*`, `docs/*`, `.agents/sessions/context-baseline-25k/` are not ours — do not stage or edit them.

## Risks / open questions
- Fail-closed `?? true` could over-deny exotic-but-safe tmux commands whose segment parse returns undefined (e.g. `tmux new-session -d && tmux ls` — currently parsed, fine; substitution forms already denied by hasActiveCommandSubstitution). Existing tmux-test allow tests will surface any regression in T5.
- RF-3 is labeled "Optional consistency" by the reviewer, but it is open-BLOCKING in the gate, so it must be resolved (align or explicit intentional-deny test).
39 changes: 39 additions & 0 deletions .agents/sessions/terminal-policy-repair-2026-08/SPEC.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# SPEC — Terminal policy repair after reviewer gate (2026-08)

## Overview
The blanket "no raw newlines" terminal policy was removed from `evaluateTerminalCommandPolicy` (done, policy tests 33/33 green, typecheck hooks green). The reviewer gate returned 6 blocking findings (RF-1..RF-6) that must be repaired before the gate clears. All work is confined to two files:

- `sdk/src/tools/terminal-command-policy.ts`
- `sdk/src/__tests__/terminal-command-policy.test.ts`

Current snapshot fingerprint (use the harness-provided full value at execute time): `v3:7fa30d019b80a…` (files=sdk/src/tools/terminal-command-policy.ts, sdk/src/__tests__/terminal-command-policy.test.ts).

## Open findings (each repair edit must cite at least one)
- RF-1-4391b95f: tmux-test mutation/executable/git guards fail open when `splitReadOnlyShellSegments` returns undefined (`segments?.some(...) ?? false`). `touch workspace.txt;`, `tee workspace.txt;`, `rm -rf src &` never hit `hasUnsafeTmuxFileMutation`/`hasUnsafeTmuxExecutable`. Read-only correctly denies on `!segments`; tmux must fail closed the same way.
- RF-2-327c10c4: add tmux-test cases for trailing `;`, `;;`, leading `;`, and background `&` around mutators (touch/tee/rm) asserting `allowed===false`.
- RF-3-fa741f2a: git-commit allow regex only accepts `-m`; `hasPlaceholderCommitMessage`/`stripCommitMessageArgs` handle `--message`/`--message=`. Real `git commit --message "Fix"` gets a generic deny. Align allow with `--message` or encode the intentional deny in a test.
- RF-4-7b925458: test coverage missing for changed behavior.
- RF-5-e9fa653a: requirement: restricted profiles fail closed on unsafe/unparseable shell composition.
- RF-6-7a8c09df: requirement: behavior-changing policy paths have meaningful test coverage.

## Requirements
- R1 (RF-1, RF-5): Every tmux-test unsafe-detector built on `splitReadOnlyShellSegments` must treat an `undefined` parse as unsafe (fail closed), matching the existing read-only `!segments → deny` posture.
- R2 (RF-2, RF-4, RF-6): New adversarial test cases in `terminal-command-policy.test.ts` for unparseable/malformed composition around mutators under tmux-test, plus allow/deny coverage for any git-commit message-flag change.
- R3 (RF-3): `git commit --message "Fix"` and `--message=…` are either accepted by the allow clause or explicitly tested as intentionally denied. Preferred: extend the allow regex to accept `-m`/`--message` (both spaced and `=` forms), since other helpers already parse them.
- R4: Do not weaken other guards (git-commit substitution denial incl. double-quoted `$(`/backticks, path containment, workspace deny patterns, validation-diagnosis heredoc handling).

## Non-goals
- No refactor of the policy module structure; minimal diff.
- No changes to `run-terminal-command.ts`, git-discipline guidance, docs, or `.agents/sessions/*` history files.
- No re-introduction of the blanket raw-newline ban (already intentionally removed).

## Acceptance criteria
- A1: `bun test sdk/src/__tests__/terminal-command-policy.test.ts` passes including the new tmux-test fail-closed cases and git-commit `--message` cases.
- A2: File-change hooks (`bun run typecheck`, `cd sdk && bun run typecheck`) pass.
- A3: A fresh snapshot-bound code-reviewer clears RF-1..RF-6 with no new blockers.

## Relevant code anchors (verify fresh before editing)
- `splitReadOnlyShellSegments` (~line 458): returns `undefined` for substitution/backtick, background `&`, or any empty segment (trailing/leading `;`, `;;`).
- tmux-test block in `evaluateTerminalCommandPolicy` (~line 1103): `workspaceWriteSyntax` array of detectors; dependent detectors use `segments?.some(...) ?? false`.
- `hasUnsafeTmuxExecutable` (~line 427) and its siblings (`hasUnsafeTmuxFileMutation`, `hasUnsafeTmuxSedInPlace`, `hasUnsafeTmuxGitCommand`, `hasUnsafeTmuxWriteRedirection`, `hasActiveTmuxCompoundShellSyntax`) — the fail-open `?? false` sites.
- git-commit allow clause (~line 1210): `^git\s+commit\s+(?=.*-m(?:\s|$)).+` guards the commit allow.
10 changes: 10 additions & 0 deletions .agents/sessions/terminal-policy-repair-2026-08/STATE.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"schemaVersion": 2,
"slug": "terminal-policy-repair-2026-08",
"status": "completed",
"currentTask": null,
"revision": 2,
"checkpoint": null,
"createdAt": "2026-08-04T15:19:32.655Z",
"updatedAt": "2026-08-04T21:04:52.635Z"
}
34 changes: 34 additions & 0 deletions .agents/sessions/terminal-policy-repair-2026-08/STATUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# STATUS — Terminal policy repair (2026-08-04)

## Current state
- Mode: plan. Gate: PENDING (blocked) with 6 open reviewer findings RF-1..RF-6 on snapshot `v3:7fa30d019b80a…`.
- Raw-newline ban removal: implemented; `bun test sdk/src/__tests__/terminal-command-policy.test.ts` was 33/33 green; typecheck hooks green.
- Reviewer pass: BLOCKING on tmux-test fail-open `?? false` guards, missing tmux fail-closed tests, git-commit `-m` vs `--message` inconsistency, missing coverage/requirements.
- Repair-editor spawn attempt failed earlier — next execution must include the full structured `handoff` object (see PLAN.md execution notes).

## Completed
- Blanket raw-newline ban removed from `evaluateTerminalCommandPolicy`.
- Newline-aware composition handling added (`normalizeCommand` preserves newlines; `hasUnquotedShellSyntax` treats unquoted newlines as syntax; `splitReadOnlyShellSegments` splits on newlines incl. `\r\n`; validation-diagnosis heredoc strip retained with narrow multi-line fail-closed guard).
- Test update: multi-line multi-command composition still denied under restricted profiles; reason no longer the blanket newline message.
- Local validation: policy tests 33/33 pass; `bun run typecheck` + sdk typecheck pass.

## Blocked on
- RF-1-4391b95f, RF-2-327c10c4, RF-3-fa741f2a, RF-4-7b925458, RF-5-e9fa653a, RF-6-7a8c09df — see PLAN.md T1–T6.

## Next checkpoint
T5 validation run after repair; then T6 fresh reviewer pass. GATE: PASSED is the completion signal.

## Resume instructions
In execute mode: work PLAN.md T1→T6 in order. Use repair-editor with full handoff citing the RF IDs and the harness-provided snapshot fingerprint. Do not touch the unrelated dirty paths listed in PLAN.md risks.

<!-- update_plan_status:appended -->
## RF tee findings status — 2026-08-04T15:19:32.653Z

RF-1-999e85ef / RF-2-356e9c97 claim tee is missing from TMUX_UNSAFE_EXECUTABLES. Live code at sdk/src/tools/terminal-command-policy.ts:267 already includes 'tee'. hasUnsafeTmuxExecutable + resolveTmuxCommand cover bare, command/env-wrapped, and /usr/bin/tee. Suite bun test sdk/src/__tests__/terminal-command-policy.test.ts: 35 pass / 0 fail including "blocks tmux agents from direct workspace mutation". No further source edit required for these RF IDs; needs fresh matching reviewer pass to clear open records.


<!-- update_plan_status:appended -->
## Session complete — 2026-08-04 — 2026-08-04T21:04:52.635Z

All six reviewer findings RF-1..RF-6 verified as already resolved in the live tree during resume; no new source edits were required. Validation green: `bun test sdk/src/__tests__/terminal-command-policy.test.ts` 35/35 pass; `cd sdk && bun run typecheck` clean. Runtime gate: GATE PASSED (no edited files; reviewer verdict LOOKS_GOOD). Session is complete — safe to archive.

Loading
Loading