diff --git a/ROADMAP.md b/ROADMAP.md index f269d332..53bd27de 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -6717,3 +6717,5 @@ Original filing (2026-04-18): the session emitted `SessionStart hook (completed) 581. **Terminal markdown renderer drops styling inside link labels because link text is accumulated as raw text while emphasis/inline-code events inside links are flattened before final rendering** — dogfooded 2026-05-22 from the `#clawcode-building-in-public` 13:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with branch/origin `docs/roadmap-workdir-provenance@8c4b33d`. Active tmux sessions at probe time: `gajae-issue-341-post-merge-cleanup-retention`, `omc-issue-3087-windows-hud-execfile`; no active claw-code implementation session. Code inspection: `rust/crates/rusty-claude-cli/src/render.rs::RenderState::append_raw` diverts all text into `link_stack.last_mut().text` whenever a link is open. `Event::Start(Tag::Emphasis)`, `Strong`, and inline `Code` still update global style/rendering, but when the current context is a link, the rendered text is appended to `LinkState.text` as plain accumulated label text. At `Event::End(TagEnd::Link)`, the renderer emits one uniformly underlined blue `[label](destination)` string. This means markdown like `[**important** docs](https://...)`, `[*emphasis* link](...)`, or ``[`code` API](...)`` loses bold/italic/inline-code styling inside the label, and ANSI escape sequences from nested inline code can be embedded into the label string before the final link styling in ways not covered by tests. Existing link coverage only asserts a simple `[Claw](url)` label. **Required fix shape:** (a) decide whether link labels should preserve nested inline styles or intentionally flatten them; (b) if preserving, store rendered segments or nested style spans in `LinkState` instead of one raw label string; (c) if flattening, strip ANSI/control styling from accumulated labels before final link render and document the limitation; (d) add tests for bold/emphasis/code inside links and nested links/images where the parser permits them; (e) ensure streaming chunk boundaries do not split ANSI state inside a link label. **Why this matters:** terminal rendering is the user-facing event log. Links often carry emphasized API names or inline-code identifiers; flattening or double-styling labels makes important documentation output less readable and can leak nested ANSI into one final styled link span. Source: gaebal-gajae dogfood response to Clawhip message `1507367459689201715` on 2026-05-22. 582. **Terminal table renderer ignores markdown alignment markers, so right/center-aligned numeric columns are rendered left-aligned with no test coverage** — dogfooded 2026-05-22 from the `#clawcode-building-in-public` 13:30 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with branch/origin `docs/roadmap-workdir-provenance@ccb319a`. Active tmux session at probe time: `omx-issue-2466-ultragoal-get-goal-recovery-resume`; no active claw-code implementation session. Code inspection: `rust/crates/rusty-claude-cli/src/render.rs` starts tables with `Event::Start(Tag::Table(..))` but discards the alignment vector carried by pulldown-cmark. `TableState` stores headers/rows/current cells only, and `render_table_row` always writes the cell text followed by padding spaces (`left` alignment) regardless of whether the markdown separator uses `:---`, `---:`, or `:---:`. Existing test `renders_tables_with_alignment` checks column width alignment only, using `| ---- | ----- |`, and does not cover right/center alignment semantics. **Required fix shape:** (a) store pulldown-cmark table alignment metadata in `TableState`; (b) apply left/center/right padding in `render_table_row` for headers and body cells; (c) add tests for `| left | center | right |` with `| :--- | :---: | ---: |`, including numeric columns; (d) ensure `visible_width` still handles ANSI-styled header cells correctly when padding is split before/after centered text; (e) document whether terminal rendering intentionally supports GitHub-style table alignment. **Why this matters:** tables are common in status reports, benchmarks, and cost/test summaries. Dropping right alignment makes numeric columns harder to scan and means the terminal renderer does not faithfully reflect markdown that users expect from GitHub/Discord-style output. Source: gaebal-gajae dogfood response to Clawhip message `1507375004671672391` on 2026-05-22. + +583. **`PermissionEnforcer::check_file_write` uses string-prefix workspace checks, so relative traversal like `../../outside` is allowed as if it were inside the workspace** — dogfooded 2026-05-22 from the `#clawcode-building-in-public` 14:00 UTC nudge on `/home/bellman/Workspace/claw-code-pr2967` with branch/origin `docs/roadmap-workdir-provenance@aa9efe5`. Active tmux session at probe time: `omx-issue-2468-autoresearch-docs-css`; no active claw-code implementation session. Channel context included Jobdori's #591 `Prompt`-mode bypass in `permission_enforcer.rs`, so this probe inspected the adjacent file-write boundary helper. Code inspection: `rust/crates/runtime/src/permission_enforcer.rs::is_within_workspace` treats relative paths by string-concatenating `format!("{workspace_root}/{path}")`, then checks `normalized.starts_with(root) || normalized == workspace_root.trim_end_matches('/')`. It never normalizes `.`/`..`, canonicalizes symlinks, or resolves the candidate path. Therefore `check_file_write("../../outside/secret.txt", "/workspace")` builds `/workspace/../../outside/secret.txt`, which still starts with `/workspace/`, and returns `Allowed` in `WorkspaceWrite` mode even though the resolved target is outside the workspace. Existing tests cover absolute outside paths and simple relative `src/main.rs`, but not relative traversal escapes. **Required fix shape:** (a) replace string-prefix checks with path normalization/canonicalization against a workspace root, resolving `.`/`..` before comparison; (b) reject escaping relative paths even if the file does not exist yet, using lexical normalization plus parent canonicalization where needed; (c) add regressions for `../outside.txt`, `../../outside/secret.txt`, `src/../safe.txt`, and symlink escape cases; (d) share the same boundary primitive with runtime file ops and bash path-scope checks so permission enforcement cannot drift; (e) include resolved/candidate path evidence in denial messages without leaking sensitive contents. **Why this matters:** workspace-write mode's core promise is “project files only.” A string-prefix check lets a caller smuggle outside writes through relative traversal while the permission enforcer reports success, defeating the boundary before lower-level file tools can help. Source: gaebal-gajae dogfood response to Clawhip message `1507382558340681779` on 2026-05-22.