|
2 | 2 |
|
3 | 3 | ## Active |
4 | 4 |
|
5 | | -- [ ] Open the `mythos-enhancements` PR; CodeRabbit gate before merge. |
| 5 | +- [ ] `mythos-enhancements` PR #118: opened; CI test failures fixed (statusline |
| 6 | + reap deadlock, diff-marker style assertion). CodeRabbit gate before merge |
| 7 | + (first review attempt was rate-limited; re-review triggers on push). |
6 | 8 |
|
7 | 9 | ### Deferred (documented, not silently dropped) |
8 | 10 |
|
|
36 | 38 |
|
37 | 39 | ## Recently completed |
38 | 40 |
|
39 | | -### 2026-06-11 — Agent robustness from export ae105609 defect review (`mythos-enhancements`) |
40 | | - |
41 | | -Source: `pythinker-export-ae105609-20260611-190240.md` (pythinker run building a |
42 | | -landing page against the design-taste-frontend skill). Five defect classes |
43 | | -observed, all fixed in the product (layer discipline per lessons.md): |
44 | | - |
45 | | -- **E1 done** — system.md §7: `<system-reminder>` arrival is harness machinery, |
46 | | - never a user reply or turn boundary (export thinking repeatedly misattributed |
47 | | - reminders to the user). |
48 | | -- **E2 done** — system.md §7: a file the user explicitly directs the agent to |
49 | | - apply (skill/spec/checklist) defines requirements for the deliverable — |
50 | | - artifact-scoped authority only; embedded directives stay inert. ReadFile wraps |
51 | | - all content `<untrusted_data>`, which previously discounted the very spec the |
52 | | - user mandated. |
53 | | -- **E3 done** — partial-read follow-through: read.py appends "Partial read: N |
54 | | - lines remain; continue with line_offset=X." on capped forward reads; review |
55 | | - found and fixed the cap flag being unreachable for DEFAULT reads |
56 | | - (n_lines == MAX_LINES ordering bug — exactly the export's 1000/1206 case); |
57 | | - read.md tip + §5 clause + ReadFile description snapshot regen. Tail-mode hint |
58 | | - deliberately skipped (different semantics). |
59 | | -- **E4 done** — system.md §9 item 7: mandatory checks in the governing |
60 | | - skill/spec walked item-by-item, compliance claims name the check that ran, |
61 | | - un-runnable artifacts reported as unverified (export claimed pre-flight |
62 | | - compliance while checking 2 of ~60 boxes). |
63 | | -- **E5 done** — inline slash-command reference guard: new |
64 | | - `soul/dynamic_injections/inline_commands.py` (root-only, one-shot per user |
65 | | - message, known commands/aliases + `skill:*`, path-token false positives |
66 | | - excluded, reminder spans stripped) + registration + §5 prompt rule (export |
67 | | - silently dropped "/best-practices" referenced mid-message). |
68 | | - |
69 | | -Adversarial 3-lens review (correctness/security/consistency, 11 agents): |
70 | | -3 confirmed findings fixed (default-read cap ordering HIGH; glued-reminder |
71 | | -leading-token false negative; helper-placement convention), 5 rejected as |
72 | | -false positives (incl. "§7 carve-out weakens injection defense" — the inert- |
73 | | -directives clause and user-gating hold). Verified: tests/ 5248 passed pre-fix |
74 | | -+ targeted 60 post-fix, tests_e2e 65 passed, make check clean; full gate |
75 | | -re-run before commit. Out of scope (deferred): WriteFile "successfully |
76 | | -overwritten" message on brand-new files is misleading; tail-mode partial-read |
77 | | -hint. |
78 | | - |
79 | | -### 2026-06-11 — Agent robustness arc (`mythos-enhancements`): spec/profile truth, jail hardening, orchestration discipline, codename task ids |
80 | | - |
81 | | -Source: live assessment of a review session (reviewers' mandated Context7/web |
82 | | -freshness check was dead code under their own permission profiles) + verified |
83 | | -triage of the follow-up deep-scan session ace53ad5. |
84 | | - |
85 | | -Decisions: reviewer-class agents (review/code-reviewer/security-reviewer, |
86 | | -judge, verifier, debugger, explore) stay OFFLINE — untrusted-diff exfiltration |
87 | | -posture wins; specs rewritten offline-honest with a structured |
88 | | -`needs verification — <library> <version>: <claim>` RISKS contract for the |
89 | | -parent to resolve (directly or via `scout`). `scout` was accidentally offline |
90 | | -(unmapped → read_only): now `scout → ask` in `_SUBAGENT_PROFILES`. No MCP |
91 | | -carve-out (fail-closed stands); dead `mcp__context7__*`/`mcp__tavily__*` and |
92 | | -SearchWeb/FetchURL entries removed from non-implement specs; plan/scout route |
93 | | -docs work through live web tools. verifier/planner/ask/debug/coder/implementer |
94 | | -audited — already consistent, untouched. |
95 | | - |
96 | | -Landed (all TDD red→green): |
97 | | - |
98 | | -- Specs: code_reviewer/security_reviewer/review offline rewrite (+ timeout |
99 | | - discipline: narrow scope on timeout, never re-run bigger; decomposition |
100 | | - hint in when_to_use); judge → offline external-claims gate; debugger → |
101 | | - installed-source-first; explore offline text; plan/scout web-first routing. |
102 | | -- system.md §5 "Review fan-out & finding verification": scope measured at the |
103 | | - merge base (committed + worktree — never the uncommitted-only stat); |
104 | | - >~1,500 lines / 25 files → one reviewer per subsystem + dedup; adversarial |
105 | | - verification (re-read cited lines, re-derive failure; drop or reject — |
106 | | - never severity-launder); re-anchor + recount; verify only third-party |
107 | | - needs-verification claims against live docs; query hygiene at the |
108 | | - network-holding layer. §8: findings reports are judge-gate triggers; child |
109 | | - severities reported as scored, never silently re-graded. `scout` added to |
110 | | - the §5 role enumeration. deep-scan.md playbook updated to match. |
111 | | -- permission.py: `scout → ask`; escape denials name the workspace root; |
112 | | - workspace-jail bypass family closed — `$VAR`/backtick path args rejected |
113 | | - fail-closed (patterns/program args unaffected — extractors never emit them |
114 | | - as paths), glob args checked by literal prefix (`rg x /etc/*`, `ls ../*`, |
115 | | - glob-then-`..` denied; in-workspace globs + `cat /etc/*` parity preserved), |
116 | | - `cd`/`pushd` tracked across segments via effective_dir |
117 | | - (`check_shell_path_argument` gains `base_dir`; `resolve_shell_path` |
118 | | - helper); `popd`/`cd -`/bare `cd`/`(`/`{` grouping rejected as untrackable. |
119 | | -- config.py: `tui.statusline.{enabled,segments,command_timeout_ms}` join |
120 | | - `command` in SCOPE_LOCKED_PATHS (cosmetics stay project-scope); |
121 | | - `command_timeout_ms` bounded `le=60_000`. |
122 | | -- subprocess_env.py: scrub adds exact PRIVATE_KEY/JWT/COOKIE/BEARER + |
123 | | - `_JWT`/`_COOKIE`/`_BEARER` suffixes (CSRF_TOKEN already via `_TOKEN`). |
124 | | -- shell: retry hard-stop keys on whitespace-normalized command |
125 | | - (`_failure_key`) so padding can't mint a fresh counter. |
126 | | -- TaskOutput wait discipline (cffe7da6 follow-up): timeout hint reordered to |
127 | | - notification-first; consecutive blocking timeouts escalate via |
128 | | - `note_blocking_timeout` ("STOP waiting" at #2); a timed-out blocking |
129 | | - attempt no longer resets the non-blocking "STOP polling" streak |
130 | | - (deliberate contract change, test rewritten). |
131 | | -- Background agent task ids are codenames (`agent-tidal-wren`): the task id is |
132 | | - the visible handle in TaskOutput/TaskStop headers, TaskList, and |
133 | | - notifications, and single background launches never got a codename. |
134 | | - `generate_task_id` mints codename ids unique against the store |
135 | | - (length-guarded vs `_VALID_TASK_ID`, random fallback); bash ids unchanged |
136 | | - but collision-checked. |
137 | | -- Docs: agents.md tool table + offline-by-design note. CHANGELOG: 11 bullets. |
138 | | - |
139 | | -Deep-scan ace53ad5 triage verdicts (adversarially verified against code): |
140 | | -$VAR jail bypass REAL for search/traversal (cat example was design-permitted |
141 | | -ReadFile parity) — fixed above with the additionally-discovered absolute-glob |
142 | | -gap; cd bypass REAL — fixed; statusline scope gap REAL (low) — fixed; |
143 | | -timeout bound REAL — fixed; scrub gaps PARTIAL (overstated) — fixed; retry |
144 | | -normalization by-design-nit — fixed. FALSE POSITIVES rejected: usage.py fence |
145 | | -parsing (documented deliberate behavior, usage.py:123-126) and notification |
146 | | -output_path "disclosure" (the documented resume contract). Orchestration |
147 | | -gaps in that session (wrong scope measurement → no decomposition; no |
148 | | -adversarial verify; silent re-scoring; judge skipped; double-block 300s) |
149 | | -addressed via the §5/§8 prompt hardening + the TaskOutput contract above. |
150 | | - |
151 | | -Verified: full tests/ 5201 passed / 7 skipped / 1 xfailed + tests_e2e 65 |
152 | | -passed + make check-pythinker-code "All checks passed!" after the spec arc; |
153 | | -post-hardening suites green per-slice (permission 56, config 77, |
154 | | -subprocess_env 7, background tools+pkg 116, agent suites 100); final full |
155 | | -gate re-run before commit (see session log). Memory + lessons.md updated |
156 | | -(spec/profile consistency invariant; identity-surface triage). |
157 | | - |
158 | | -### 2026-06-11 — Deep-scan report validation + robust nitpicks (parallel pass) |
159 | | - |
160 | | -Validated .pythinker/reports/mythos-enhancements-deep-scan.md against the |
161 | | -already-fixed working tree: High $VAR + Medium cd bypass already closed; |
162 | | -statusline/timeout findings already locked; fence-parsing "fix" would regress |
163 | | -the aggregator (by-design). Locked the two tightenings with extra tests: |
164 | | -tests/tools/test_shell_retry_guard.py (4 tests — key normalization + |
165 | | -_record_failed_attempt dedup) alongside the existing scrub false-positive |
166 | | -guards. Verified: 35 passed (shell_bash + retry_guard + subprocess_env). |
167 | | - |
168 | | -### 2026-06-11 — TUI streaming polish (parallel sessions) |
169 | | - |
170 | | -- Transient red `<invalid>` flash on streaming tool calls: while args stream, |
171 | | - partial-JSON repair turns key-without-value into `null` and card renderers |
172 | | - flashed `<invalid>`. Central fix in `_blocks.py:_compose_card`: drop |
173 | | - None-valued keys while args are incomplete so renderers show their pending |
174 | | - state; finished calls with invalid args still show `<invalid>`. |
175 | | - Tests: test_tool_call_block.py char-by-char streaming guards (red→green). |
176 | | -- Streaming redraw smoothness (macOS terminals): DEC mode 2026 synchronized |
177 | | - updates — `ui/shell/sync_output.py` brackets every frame in |
178 | | - `\x1b[?2026h…l` via a patched session-output flush (renderer frames + |
179 | | - patch_stdout prints), gated by |
180 | | - `terminal_capabilities.synchronized_output_enabled()` (TERM=dumb off; |
181 | | - kill switch `PYTHINKER_NO_SYNC_OUTPUT=1`). 8 new tests; ui_and_conv 1752 |
182 | | - passed; PTY smoke shows BSU/ESU marks. |
183 | | - |
184 | | -### 2026-06-11 — Live-session follow-ups |
185 | | - |
186 | | -TaskOutput blocking-timeout retry-loop investigation (fix shipped in the |
187 | | -robustness arc above); distinctive RunAgents instance codenames |
188 | | -(subagents/codenames.py); slash-command inline ghost completion + Tab accept |
189 | | -(SlashCommandAutoSuggest in ui/shell/prompt.py + theme styles + key binding). |
190 | | - |
191 | | -### 2026-06-11 — CodeRabbit review triage (16 findings) |
192 | | - |
193 | | -Fixed (7): RunMeta.requested_base_ref → `str | None`; constant.py catches |
194 | | -TOMLDecodeError; prompt.py CwdLostError re-raises caught instance; prompt.py |
195 | | -shortstat bare-except now debug-logs; otel.py error-log sink one-shot |
196 | | -breadcrumb; usage.py `none observed` placeholders (+ regression test); symlink |
197 | | -test skips when unsupported. |
198 | | - |
199 | | -Declined as false positives (evidence): 4× "subagents: null → []/{}" |
200 | | -(agentspec.py:60 types `dict|None|Inherit`, :128 resolves `or {}`; bare |
201 | | -`subagents:` is the uniform 15-spec convention; `[]` would fail pydantic); |
202 | | -agent.py add_shared_tools ordering (toolset.py:981 registers every connected |
203 | | -MCP tool on the primary toolset anyway — proposed move is a no-op); CHANGELOG |
204 | | -duplicate bullets (title-level scan finds zero). |
205 | | - |
206 | | -### 2026-06-11 — Agent review safety + TUI hardening (`mythos-enhancements`) |
207 | | - |
208 | | -Plan: docs/superpowers/plans/2026-06-11-agent-review-safety-tui-hardening-plan.md. |
209 | | -Landed: workspace jail for shell path args (`check_shell_path_argument` + |
210 | | -`shell_workspace_escape_reason` wired into `check_shell_command_allowed`, |
211 | | -fg+bg shared); declarative profiles (`allow_network` on PermissionProfile, |
212 | | -SearchWeb/FetchURL hidden AND execution-denied for review/verify/read-only, |
213 | | -yolo non-escalation locked by tests); secret env scrubbing for |
214 | | -restricted-profile shell (incl. background via TaskSpec.scrub_secrets); |
215 | | -bounded retry (verbatim command after 2 failures ⇒ hard denial, |
216 | | -review-scoped); ResolvedDiff/RunMeta `requested_base_ref`/`fallback_reason` |
217 | | -(loud origin/main fallback); subagent todos normalized to single in_progress; |
218 | | -monotonic _ToolCallBlock guards. Key decisions: jail mirrors file-tool |
219 | | -semantics (Glob/Grep full jail; ReadFile parity) so Shell is never stricter |
220 | | -than first-class tools; `_SUBAGENT_PROFILES` stays the single profile |
221 | | -registry. Verified then: make check ✓, review pkg 170 ✓, tests/ 5170 ✓, |
222 | | -tests_e2e 65 ✓; clean-code-guard pass deduplicated Shell failure-count |
223 | | -increment (`_record_failed_attempt`) and todo note-rebuild. |
224 | | - |
225 | | -### 2026-06-11 — Default best-practices adoption (`feat/agentic-orchestration`) |
226 | | - |
227 | | -`prompts/best_practices.md` upgraded to the enhanced 15-section profile (`/bp` |
228 | | -section parsing intact) + condensed always-on `## Default Best Practices` |
229 | | -baked into agents/default/system.md (inherited by all roles). Pins updated |
230 | | -(test_best_practices_slash.py, test_default_agent.py); docs + CHANGELOG. |
231 | | -Verified: targeted 46 passed, e2e wire snapshot + parity 5 passed, make check |
232 | | -clean. Placement after `## Engineering Discipline`; condensed bullets cover |
233 | | -only the delta; inline-comments rule deliberately excluded (would conflict |
234 | | -with system.md code-quality defaults). |
235 | | - |
236 | | -### 2026-06-11 — Agentic UX enhancements (`feat/agentic-orchestration`) |
237 | | - |
238 | | -`4302f457` /statusline customizable status bar (StatusLineConfig + |
239 | | -ui/shell/statusline.py + card-footer wiring + slash command + docs); |
240 | | -`fe165e59` concurrent foreground RunAgents fan-out (bounded by |
241 | | -background.max_running_tasks; ordering preserved; sibling-failure isolation) |
242 | | -+ batch_risks/batch_blockers roll-up in subagents/usage.py. Verified: full |
243 | | -suite 5005, tests_e2e 65, make check green. Deviations: interactive picker |
244 | | -deferred in favor of subcommands; customization applies to the card-footer |
245 | | -style. Out of scope: DAG/workflow engine; maintainer deferrals (mcpext-2(a), |
246 | | -obs-eval-3/4 live wiring, `lexical_recall`). |
247 | | - |
248 | | -### 2026-06-11 — Clean-code-guard scan of feat/agentic-orchestration (full branch) |
249 | | - |
250 | | -Scope: `git diff main` against the worktree (committed + uncommitted), ~3000 |
251 | | -lines across 51 files. Fixed three bugs: (1) `_extract_section` stripped a |
252 | | -leading `-`/`*` from NON-bulleted finding lines, mangling bare `--force`/`*args` |
253 | | -findings — now only `- `/`* ` bullet markers strip (usage.py); (2) `/statusline` |
254 | | -verb parsing used `startswith`, so `/statusline commands` persisted external |
255 | | -command `"s"` and reloaded — now exact-verb `partition` match (ui/shell/slash.py); |
256 | | -(3) capped-output `proc.kill()` in `StatusLineCommandRunner._run_command` was |
257 | | -the only kill not wrapped in `suppress(ProcessLookupError)` — race logged as a |
258 | | -spurious refresh failure (statusline.py). Plus a docstring drift fix in |
259 | | -`_intercept_shell_command`. Regression tests added for (1) and (2). Verified |
260 | | -non-issues: `is_terminal_status` includes "recoverable" deliberately; |
261 | | -`ToolReturnValue.output` isinstance guard is real; `_rich_escape` is a local |
262 | | -helper; RunAgents gather doesn't swallow CancelledError. Verified: full unit |
263 | | -suite 5059 passed, make check-pythinker-code green. |
264 | | - |
265 | | -### 2026-06-11 — Deep-scan report triage (statusline runner + findings roll-up) |
266 | | - |
267 | | -Confirmed & fixed (statusline.py): refresh-loop exception guard, explicit |
268 | | -interval clamped to a positive floor, bounded 64KiB stdout read replaces |
269 | | -communicate(), sync cancel() also kills a live child process, _warn_once |
270 | | -dedupes per message. usage.py: _extract_section now skips fenced code blocks. |
271 | | -Rejected as not-issues: mid-task /statusline Reload (caught by |
272 | | -_run_slash_command_during_task), self-configured command exec+shlex (by |
273 | | -design), child output unwrapped (same-tier LLM content), BaseException |
274 | | -passthrough (correct). Regression tests added for every fix. |
275 | | - |
276 | | -### 2026-06-11 — Per-command during-task availability for shell slash commands |
277 | | - |
278 | | -`SlashCommand.available_during_task` flag; task-safe read-only commands |
279 | | -(/statusline, /usage, /help, /version, /agents, /changelog, /context, /tools) |
280 | | -run immediately mid-task via `_intercept_shell_command()` + |
281 | | -`shell_command_runner` hook; the rest toast "disabled while a task is in |
282 | | -progress". `Shell._run_slash_command_during_task` swallows Reload/Switch |
283 | | -mid-turn with a "saved, applies later" notice. Bare `/statusline` opens a |
284 | | -dismissable settings-list menu at the idle prompt; completion popup annotates |
285 | | -blocked-mid-run commands. Tests: test_btw.py, test_statusline_slash.py, |
286 | | -test_slash_completer.py; full ui_and_conv, core, utils, tests_e2e green. |
287 | | - |
288 | | -### 2026-06-11 — Port upstream tool-call dedup (kimi-cli #2242 + #2372) |
289 | | - |
290 | | -soul/toolset.py: canonical args, same-step result sharing, cross-step sparse |
291 | | -reminders (streak 3/5/8), dedup telemetry. soul/pythinkersoul.py: per-turn |
292 | | -reset, `begin_step` inside the step-retry wrapper, `end_step` after tool |
293 | | -results, D-Mail revert clears the dedup seed. 9 upstream dedup tests ported |
294 | | -(25 total green). Verified: full suite minus PTY e2e 4852 passed; make check |
295 | | -green. Skipped #2372 drive-bys (promo banner, /clear→/new alias). |
296 | | - |
297 | | -### Dropped: `pythinker-cli` → `pythinker-code` rename plan (2026-05-07) |
298 | | - |
299 | | -Obsolete — the rename is already fully realized: root `pyproject.toml` is |
300 | | -`name = "pythinker-code"`, the module is `src/pythinker_code/`, and zero |
301 | | -`pythinker_cli` references remain in source. |
302 | | - |
303 | | -### 2026-06-11 — Bugsink noise: suppress expected user-environment errors |
304 | | - |
305 | | -Triaged all 16 open issues on errors.pythinker.com (raw events archived in |
306 | | -tasks/bugsink_issues.json + tasks/bugsink_raw_events.json). telemetry/errors.py |
307 | | -gains `is_expected_error()` (cause-chain walk; 401/403/408/429/5xx, timeouts, |
308 | | -connection/DNS errors, OAuthError, McpError METHOD_NOT_FOUND); |
309 | | -`report_handled_error()` tags OTel `expected=` and skips Sentry capture for |
310 | | -expected ones. telemetry/crash.py asyncio handler applies the same gate; |
311 | | -sys.excepthook deliberately NOT gated. grep_local.py rg exec OSError (wrong |
312 | | -arch) now falls back to `_python_grep`. Tests: expected-error matrix, |
313 | | -crash-gate, rg-exec fallback. Verified: full suite 5018 passed; checks clean. |
314 | | -Out of scope: 400 "enable_thinking" is upstream pythinker_core compat. |
315 | | - |
316 | | -### 2026-06-11 — Telemetry release sync + SigNoz pipeline & dashboard setup |
317 | | - |
318 | | -constant.py `get_version()` prefers live pyproject.toml in source checkouts; |
319 | | -telemetry/config.py `detect_environment()` wired into sentry AND otel resource. |
320 | | -Infra: otel.pythinker.com had no Traefik route (404) — all client OTLP dropped |
321 | | -since launch; fixed with collector labels (port 4318) + redeploy, verified |
322 | | -end-to-end. SigNoz: product dashboard (12 panels), 5 saved views, 3 alert |
323 | | -rules → pythinker-admin-email. Out of scope: edge collector bearer validation; |
324 | | -SMTP for alert delivery. |
325 | | - |
326 | | -### 2026-06-11 — Bugsink release sync (seamless) |
327 | | - |
328 | | -Bugsink project renamed pythinker-cli → pythinker-code; junk releases deleted. |
329 | | -release workflow gains `register-bugsink-release` job POSTing |
330 | | -`pythinker-code@<version>` at tag time (idempotent; failures are warnings). |
331 | | -Secret `BUGSINK_RELEASES_TOKEN` set on the repo. |
332 | | - |
333 | | -### 2026-06-11 — system.md harmonization + deep-scan fixes (`feat/agentic-orchestration`) |
334 | | - |
335 | | -system.md condensing pass reviewed and harmonized (one stale cross-reference |
336 | | -fixed; two prompt pins updated). High fixes: `("tui","statusline","command")` |
337 | | -scope-locked; OTel error-log forwarding now site-only (no message body) per |
338 | | -the privacy posture. Medium finding already resolved by 68fb92d0. make-check |
339 | | -cleanup of pre-existing statusline-commit failures (import order, format |
340 | | -drift, pyright in test files). Final: make check exit 0; full tests/ 5142 |
341 | | -passed. "code-reviewr" in specs is a real CLI name, not a typo. |
| 41 | +Completed-work logs through 2026-06-11 (agent robustness arc, statusline v2, |
| 42 | +review-safety hardening, telemetry sync, CodeRabbit triage) were trimmed on |
| 43 | +repush of PR #118 — see git history of this file for the full record. |
0 commit comments