Commit Graph

7 Commits

Author SHA1 Message Date
gsxdsm
7ed1c39a67 FN-9102: fix active runtime segment accounting
Prevent reopened tasks from double-counting closed execution segments while preserving pre-execution planning time.

- Clear the live execution anchor whenever a WIP segment is banked.
- Clamp legacy poisoned runtime values with separate execution and combined-work wall-clock ceilings.
- Cover cards, detail statistics, core totals, and planner metrics across WIP round trips and historical rows.
- Add a patch changeset for the published Fusion package.

Files changed:
 .changeset/fn-9102-task-runtime-double-count.md    |  7 ++
 .../src/__tests__/reopen-semantics-by-role.test.ts | 95 ++++++++++++++--------
 packages/core/src/tasks/task-timing.ts             | 20 ++++-
 .../core/src/workflows/default-workflow-hooks.ts   | 14 +++-
 .../app/components/__tests__/TaskCard.test.tsx     | 27 ++++++
 .../__tests__/TaskTokenStatsPanel.test.tsx         | 27 ++++++
 .../app/utils/__tests__/taskTiming.test.ts         | 40 +++++++++
 packages/dashboard/app/utils/taskTiming.ts         | 28 +++++--
 .../__tests__/task-planner-chat-metrics.test.ts    | 28 +++++++
 .../dashboard/src/task-planner-chat-metrics.ts     | 22 ++++-
 10 files changed, 260 insertions(+), 48 deletions(-)

Fusion-Task-Id: FN-9102

Fusion-Task-Lineage: 3b42e81f-4e11-4232-80f6-052f51b83f1c

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-08-15 13:39:24 -07:00
gsxdsm
e84e9d7f60 fix: the caller audit — five unwired parameters, five defects in their callers (#2803)
Seven fixes that were sitting on separate handoff branches with no owner
while `main` moved. Consolidated, rebased onto current `main`, and
verified **together** rather than only per-branch. The individual
branches remain if a subset is preferred.

This is the same consolidation that got `batch-core` and #2787 adopted.
**Close it if it breaks queue policy** — the branch keeps the work safe
either way.

## Where these came from

#2787's review found an optional parameter whose production caller never
passed it. That is a class, so I ran it against everything I had landed
and found five more. **All five turned out to have their real defect in
the CALLER, not the parameter** — in four of them the parameter was
unreachable:

| unwired parameter | what was actually wrong |
|---|---|
| `blocker-fanout.escalationColumns` | the hold default made the count
zero — **no bottleneck warning was emitted at all** |
| analytics `columnFlagsByName` | routes never built a map — **0
in-progress / 0 in-review beside correct cost totals** |
| `isLegacyAutoMergeStampCandidate` | the read **queried a column a
renamed board does not have**, so the backfill iterated nothing |
| `rankAssignedTasksForWakeDelta` | `getTasksByAssignedAgent`'s
`excludeArchived` used the literal — **archived cards returned as open
work** |
| `duplicate-intake.columnFlagsByColumnId` | intake could **archive or
soft-delete a newly created task** as a duplicate of finished work |

The heuristic worth keeping: **an optional parameter no production
caller fills is a marker pointing at an unexamined caller.** The census
cannot see any of these five — every gate is a `Set`/array literal or a
query filter, i.e. a definition rather than a comparison.

## Also included

- **`executor.ts`** — the stale-spec guard did the exact thing its own
comment forbids: on a renamed board it ran on a LIVE task and pulled it
out of execution into replan. `activeMergeStatuses` protected merging
cards *by accident*, which is why the symptom looked arbitrary.
- **`register-project-routes.ts`** — project health reported **0 active
tasks**; its list also still contained `triage`, dead since U11.
- **`dashboard/app/utils/taskTiming.ts`** — a **second copy** of
`getTotalAgentActiveMs`. Core's was converted; the card chip imports
this one, so the census counted the site as done while the rendered
number stayed keyed on `"in-progress"`.

## Verification

Verified as a set: `pnpm test:gate` **161 / 13 / 487 / 71** · core
suites **15 passed** · engine **7** · dashboard **12** · four `tsc`
targets clean · lint clean · census `--strict` exits 0.

Each fix is revert-proven individually; the specific case that fails is
named in each test header.

## Two honesty notes

**Three guards here are structural, not behavioural, and say so in their
headers.** `sanitizeAgentTaskLinks` is a closure inside
`createApiRoutes`; the analytics aggregators need a live
`AsyncDataLayer`; the stale-spec guard sits deep inside `execute()`.
Each ratchet fails on revert — verified — but none is an end-to-end
proof, and the headers state which half they cover.

**One of my behavioural test sets would have lied.** The intake-dedup
cases drive `findSameAgentDuplicates` directly; I removed the wiring to
measure the revert and **they stayed green**, because they pin the
predicate and not the caller. That is the exact illusion this audit was
chasing, reproduced in my own file. The forward now has its own
structural check.

## Deliberately not included

`worktree-pool.ts:1205` — it **fails safe** (a missed match protects a
branch from cleanup rather than deleting it) and sits in the merger's
branch-reaping path where the opposite error destroys work. That
deserves its owner's judgement, not a drive-by conversion.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 12:02:53 -07:00
gsxdsm
dc50425e98 docs: correct 104 future-dated FNXC timestamps across 61 files (#2680)
## What

The FNXC convention exists so a reader can place a note against the
change that motivated it. A stamp dated *after* the edit landed defeats
exactly that.

This is program-wide drift, not one author's slip — I contributed to it
in my own commits this week, which is how I noticed it.

## Measured, on this tree

**104 stamps across 61 files** dated later than the day they were
written, from one day ahead to **2026-10-19 (81 days)**:

| count | date | count | date | count | date |
|---|---|---|---|---|---|
| 50 | 2026-07-31 | 6 | 2026-08-05 | 3 | 2026-08-13 |
| 17 | 2026-08-01 | 1 | 2026-08-07 | 1 | 2026-08-19 |
| 7 | 2026-08-02 | 1 | 2026-08-12 | 2 | 2026-08-26 |
| 11 | 2026-08-03 | | | 3 | 2026-10-19 |

An earlier number I circulated was ~70. That came from a narrower
pathspec and was wrong; **104** is the measurement.

## How

Each stamp is rewritten to the date of the commit that introduced **that
line**, via per-line `git blame` — deliberately *not* stamped uniformly
with today's date. A uniform stamp swaps a wrong date for a different
wrong date and flattens the ordering that makes these comments
navigable; blame preserves it. Times of day are untouched, and a blame
date in the future is clamped rather than trusted.

## Why the verification is listed

A docs sweep across 61 files is precisely where a stray edit hides, so
the safety claims are mechanical rather than asserted:

- every changed line begins with a comment marker — **no code touched**;
- **no test asserts an FNXC date later than today**, so no `toContain`
assertion on embedded source text can be silently invalidated (several
such assertions do exist);
- CSS files, which carry several of those assertions, are outside the
pathspec.

## Verified

lint clean · merge gate green (487 + 158 + 10 + 71) · `census --strict`
exit 0 · tsc clean for core, engine, and dashboard
(`tsconfig.app.json`).

**No behavior change.** Comment text only.

## Not done here

A guard preventing recurrence. A check that rejects an FNXC stamp dated
after the commit would stop this returning, but it needs a decision
about where it runs (lint rule vs. gate) and it is a behavior change to
CI — it does not belong riding inside the sweep it would police.
2026-07-30 02:38:58 -07:00
gsxdsm
1d4e8afa7b FN-8444: include planning time in task metrics
Track active planning time alongside execution time for costs, analytics, and task displays.

- Persist planning timing state across task lifecycle transitions and recovery
- Include planning activity in token cost, analytics, and dashboard timing displays
- Add PostgreSQL migration support using the configured migration directory

Files changed:
 .changeset/fn-8444-planning-time-cost.md           |  7 +++
 docs/dashboard-guide.md                            |  3 ++
 docs/task-management.md                            |  5 ++
 packages/core/src/index.ts                         |  1 +
 .../migrations/0029_planning_active_timing.sql     |  3 ++
 packages/core/src/postgres/schema-applier.ts       | 14 ++++-
 packages/core/src/postgres/schema/project.ts       |  2 +
 packages/core/src/productivity-analytics.ts        | 29 +++++-----
 packages/core/src/store.ts                         |  2 +-
 .../core/src/task-store/archive-lifecycle-2.ts     |  2 +
 packages/core/src/task-store/moves.ts              |  7 +++
 packages/core/src/task-store/persistence.ts        |  4 ++
 packages/core/src/task-store/remaining-ops-2.ts    |  2 +-
 packages/core/src/task-store/serialization.ts      |  7 +++
 packages/core/src/task-store/task-row-mappers.ts   |  2 +-
 packages/core/src/task-store/task-update.ts        | 10 ++++
 packages/core/src/task-timing.ts                   | 35 ++++++++++++
 packages/core/src/types.ts                         | 12 +++++
 packages/dashboard/app/components/TaskCard.tsx     | 13 ++---
 .../app/components/TaskTokenStatsPanel.tsx         |  6 ++-
 .../app/components/__tests__/TaskCard.test.tsx     | 17 ++++++
 .../app/utils/__tests__/taskTiming.test.ts         |  9 +++-
 packages/dashboard/app/utils/taskTiming.ts         | 14 +++++
 packages/dashboard/app/utils/taskTokenCost.ts      |  2 +
 .../dashboard/src/task-planner-chat-metrics.ts     | 14 ++++-
 packages/engine/src/__tests__/self-healing.test.ts | 61 +++++++++++++++++++++
 packages/engine/src/executor.ts                    | 50 +++++++++++++++++
 packages/engine/src/runtimes/in-process-runtime.ts |  3 ++
 packages/engine/src/self-healing.ts                | 62 ++++++++++++++++++++++
 packages/engine/src/triage.ts                      | 10 ++++
 packages/i18n/locales/en/app.json                  |  2 +-
 packages/i18n/locales/es/app.json                  |  2 +-
 packages/i18n/locales/fr/app.json                  |  2 +-
 packages/i18n/locales/ko/app.json                  |  2 +-
 packages/i18n/locales/zh-CN/app.json               |  2 +-
 packages/i18n/locales/zh-TW/app.json               |  2 +-
 36 files changed, 384 insertions(+), 36 deletions(-)

Fusion-Task-Id: FN-8444

Fusion-Task-Lineage: 0178e0a7-3018-4ef4-be9b-6de5f964fb58

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-20 13:40:50 -07:00
Fusion
3648d1e1df feat(FN-4595): implement cumulative execution timing semantics
Fusion-Task-Id: FN-4595
Fusion-Task-Lineage: 73a3d0ad-5c10-4560-aec5-f9d138deeefd
2026-05-15 07:50:34 -07:00
Fusion
b9b6d06cad feat(FN-3622): add canonical task-detail timing calculations and stats pane
The merge lands three commits for FN-3622's canonical task timing calculations, adding `taskTiming.ts` logic and stats timing semantics to `TaskDetailModal` and `TaskTokenStatsPanel`, backed by regression tests across those panels and the root `test-changed.mjs` script. The remaining commits introdu

Fusion-Task-Id: FN-3622
2026-05-06 19:55:55 -07:00
gsxdsm
d30edfda5d feat: live task token usage and stats-tab fixes
Capture per-session token usage from pi-coding-agent's getSessionStats()
after each promptWithFallback in the executor and merger paths, so
task.tokenUsage populates live during runs and reflects final totals on
done tasks. Previously the executor never read session usage and only
the heartbeat path bumped agent token totals, leaving task.tokenUsage
undefined even after completion.

Stats panel and done-card timing also now reflect live state: the modal
overlays the SSE-updated task prop on top of the one-shot fullDetail
snapshot, in-progress workflow steps contribute live elapsed to the
Workflow runtime metric, and the done card uses Timed duration (matching
the stats tab) with workflow runtime as fallback. Time indicator labels
coarsened to <1m / Nm / Nh / Nd.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 04:51:29 -07:00