Commit Graph

4 Commits

Author SHA1 Message Date
gsxdsm
14c73ab727 U11 [tool-availability + skill-resolver + cli/task]: name the 3 literals that are NOT columns (48 -> 45) (#2619)
**Taking: `engine/tool-availability.ts`, `engine/skill-resolver.ts`,
`cli/commands/task.ts`** — the three census hits that are not board
columns.

## Census

| file | before | after |
|---|---:|---:|
| `packages/engine/src/tool-availability.ts` | 1 | **0** |
| `packages/engine/src/skill-resolver.ts` | 1 | **0** |
| `packages/cli/src/commands/task.ts` | 1 | **0** |
| **repo total (comment-stripped)** | **48** | **45** |

## These are not lifecycle guards — converting them would have been
wrong

- **`tool-availability`** — `surface: "triage" | "executor"` is an
**agent lane**. The lane that writes specs keeps its name whatever the
board calls its planning column. Resolving it from a workflow IR would
make an agent's prompt depend on board configuration.
- **`skill-resolver`** — `sessionPurpose === "triage"` is an **agent
role**. Same argument: a role doesn't move when a board renames a
column.
- **`cli task list`** — the glyph chain distinguished **active** columns
from the rest and nothing else; all four active ids mapped to the same
`●`.

Each is now named (`AgentResearchSurface`,
`ROLE_FALLBACK_SESSION_PURPOSES`, `ACTIVE_COLUMN_GLYPH_IDS`) so the next
person working the census sees at a glance that they're out of scope,
rather than re-deriving it as I had to.

## A real divergence my own equivalence test caught

I first wrote the glyph as the tempting inverse:

```ts
const dot = col === "done" || col === "archived" ? "○" : "●";
```

That is equivalent across all six lifecycle ids and **not** equivalent
for anything else — the original chain fell through to `"○"` for an
unrecognised id, while the inverse renders it as **active**. The loop
only walks the six `COLUMNS` today, so nothing would have caught it in
practice; a renamed workflow reaching this code later would have
silently changed how its columns render.

Shipped as an explicit ACTIVE set that mirrors the fallthrough exactly.
The test asserts equivalence over the six ids **and** over unknown ids,
which is where the difference lives.

That's the point of testing a "pure rename" at its edges rather than
only where it's currently exercised.

## Verification

- 71 tests green across skill-resolver / heartbeat-skills /
tool-availability / the new equivalence suite
- merge gate green (482 + 132 + 10), engine + CLI tsc clean, lint clean

## Note on the remaining count

Of the 45 left, `replan-target.ts` (2), `board-workflows.ts` (2) and
`archive-planning.ts` (1) show up in a **raw** grep but are **0** real —
every hit is inside a comment. A raw grep reports 53; comment-stripped
is 45. Real remaining work concentrates in `self-healing.ts` (11),
`register-task-workflow-routes.ts` (6), and the parked `moves.ts` /
`default-workflow-hooks.ts` (9).

No changeset: `@fusion/engine` is private; the CLI change is
display-identical.

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


---

## ⚠️ Read before merging — these are ROLE renames, not column
conversions

The coordinator's hand classification says several literals in this PR
"must be left exactly as they are" because they compare an **agent
role**, not a task column, and resolving them to a column trait would be
a bug. **I agree, and this PR does not do that.**

What it does: replaces a bare `=== "triage"` with a **named role
predicate** — `isPlanningAgentLane`, `AgentResearchSurface`,
`ROLE_FALLBACK_SESSION_PURPOSES`. Behaviour is **byte-identical** for
every input. No IR is consulted, no trait is resolved, no column is
involved.

The reason to keep it rather than revert: the danger isn't the literal,
it's that nothing at the call site tells the next person `"triage"` here
means a *lane*. A list of exceptions maintained elsewhere only helps
someone who finds the list; a call named `isPlanningAgentLane` helps
whoever is reading the line. It also shrinks what the #2630 ratchet's
ignore list has to carry.

Reversible: if the preference is to leave the literals untouched, say so
and I'll strip these hunks — but then the ratchet's ignore list must
carry **all twelve** role sites or it can never reach zero, because
those six are correct code.

## Classification finding

Bucketing by the **receiver** of the comparison (not the literal)
mechanically separates guards from roles, and it found **six role sites
currently listed as "real column guards"**:

| site | receiver | what it actually is |
|---|---|---|
| `usage-limit-detector.ts:144, 207` | `agentType` | agent type — the
column test one line above is *already* trait-driven |
| `skill-resolver.ts:432` | `sessionPurpose` | session purpose |
| `tool-availability.ts:32` | `surface` | agent surface (`"triage" \|
"executor"`) |
| `effective-model-resolution.ts:148` | `entry.agent` | agent-log lane |
| `useTasks.ts:162` | `entry.agent` | agent-log lane |

So the real bar is roughly **39**, not 45. The rule that found all
twelve without judgement calls: `column`/`toColumn`/`taskColumn`/`c` are
guards; `role`/`agent`/`agentType`/`surface`/`sessionPurpose` are not.
Worth teaching #2630's ratchet directly.
2026-07-29 23:10:11 -07:00
gsxdsm
d8f0b1a268 Restore PostgreSQL integration parity (#2089)
## Summary

- add asynchronous PostgreSQL parity to research commands and engine
execution paths
- persist Roadmap, Compound Engineering sessions, and WhatsApp state in
PostgreSQL
- harden cancellation, concurrency, reconnect, replay-claim, and
detached-promise behavior
- bundle the PostgreSQL-backed integration implementations in the
published CLI

This is PR 2 of 2 and is intentionally stacked on #2088. It contains 44
changed files; merge #2088 first, then retarget this PR to `main` if
GitHub does not do so automatically.

## Verification

- `pnpm check:changesets --strict`
- `pnpm lint`
- `pnpm test:gate`: 463 tests passed
- Compound Engineering plugin: 299 tests passed
- Roadmap plugin: 144 tests passed
- WhatsApp plugin: 27 tests passed
- research CLI: 18 tests passed
- `pnpm verify:fast`: all scoped typechecks, builds, CLI build, and boot
smoke passed

## Post-Deploy Monitoring & Validation

- deploy only after #2088 and verify schema migration `0002` is present
- monitor research cancellation, automation claims, agent execution,
plugin schema initialization, and unhandled rejections
- validate Roadmap ownership, Compound Engineering session recovery, and
WhatsApp reconnect/replay deduplication
- compare per-project plugin and workflow counts after cutover
- restore the pre-deploy backup for data rollback; avoid an in-place
schema downgrade
2026-07-14 08:17:36 -07:00
gsxdsm
cec191eac3 FN-5638: migrate pi-ai and pi-coding-agent packages to @earendil-works scope
Fusion-Task-Id: FN-5638

Fusion-Task-Lineage: 6e99c156-5f6c-42e6-bd26-618e08ffd05f
2026-05-28 21:23:48 -07:00
Fusion
aaaebdcb0d feat(FN-3706): gate research tools behind experimental feature
The merge introduces a research tool surface gating mechanism: shared availability helpers in core and engine, applied to the executor and triage agent so research prompts and tool exposure are gated behind experimental-feature flags, with tests covering the new logic.

Fusion-Task-Id: FN-3706
2026-05-07 15:53:58 -07:00