Files
clide/governance
jpmschweitzerandClaude Opus 4.7 8074bf4201 replace forkpty() with posix_openpt() + posix_spawn() (T-96)
`forkpty` calls `fork()` underneath. `fork()` in a multithreaded
process is unsafe: only the calling thread survives in the child,
but libc locks held by other threads remain "locked forever." With
the multi-threaded Dart VM as parent, ~5% of spawns deadlocked in
the child before `execve` (forensic probe: child stuck in S state
with comm=`DartWorker`, master fd never sees POLLIN).

`posix_spawn` uses `vfork` on glibc/musl/macOS, keeping the parent
suspended until execve completes — no Dart code runs in the child.
Pty pair built via the POSIX-standard `posix_openpt` / `grantpt` /
`unlockpt` / `ptsname` sequence. Probed: zero hangs in 300
sequential spawns vs ~5% before.

Behavior change: missing executable / missing workingDirectory now
surface as a `PtyException` thrown by `NativePty.start` rather than
a diagnostic written from the child to the slave PTY. Cleaner error
path for callers.

Side benefit: drops the `libutil.so.1` dynamic-library dependency.
PTY now resolves entirely against libc via `DynamicLibrary.process()`.

Splits the library-level `@Tags(['forkpty'])` on session_test.dart
into a per-test tag, so the now-runnable-under-flutter-test cases
contribute to coverage. `dart_test.yaml` declares the tag so the
exclude-tags filters honor it. Drops the `retry: 2` workaround from
the formerly-flaky registry test.

D-5 amended. Trims session-introduced CHANGELOG entries that were
over-verbose for the Keep-a-Changelog format.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 20:21:41 +02:00
..

Decisions, Questions, Rejected

This directory holds structured planning records that pql parses into pql.db. Each record is a ### [DQR]-N: Title heading inside a markdown file. Files live in three per-type subdirectories:

  • decisions/<domain>.md — confirmed design decisions
  • questions/<domain>.md — open questions that may resolve into decisions or rejected proposals
  • rejected/<domain>.md — rejected proposals (kept for the audit trail)

The parser infers domain from the filename stem and record type from the parent subdirectory.

D-records that propose implementation work link to initiative-type tickets via decision_ref. Run pql decisions show <id> --with-tickets to inspect implementation status.

Start with this canonical set; create files as records land in each domain:

  • architecture — structural commitments (storage, layering, languages, libraries)
  • process — team workflow (commits, branches, releases, reviews)
  • design — user-facing surface (UX, UI, public APIs)
  • coding-conventions — team-internal code shape (style, lint, file layout)
  • testing — quality strategy (coverage, layers, gates)

You might also want, project-permitting:

  • accessibility — if you ship user-facing software
  • security — if you handle user data or network surfaces
  • licensing — if you release open-source or commercial
  • documentation — if user-docs are non-trivial
  • deployment — if shipping is non-trivial
  • performance — if you have perf budgets / SLOs

Decisions

Open questions

Rejected