Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0f5a257
docs: start cycle 0012 conflict analyzer split
flyingrobots Apr 7, 2026
211d635
refactor: extract conflict analysis request
flyingrobots Apr 7, 2026
02a9554
docs: update slice report style
flyingrobots Apr 7, 2026
bd3ebfc
docs: archive the compiler episode script
flyingrobots Apr 7, 2026
000734e
docs: revise the compiler ending
flyingrobots Apr 7, 2026
9f55ac9
docs: archive terminal bird submission
flyingrobots Apr 7, 2026
1143ea8
docs: Enhanced Easter Egg
flyingrobots Apr 7, 2026
c2b3df2
refactor: extract ConflictAnchor as runtime-backed class
flyingrobots Apr 7, 2026
e62348f
refactor: extract ConflictTarget as runtime-backed class
flyingrobots Apr 7, 2026
bd8fbfb
refactor: add runtime-backed conflict domain types
flyingrobots Apr 7, 2026
7afc4d9
refactor: wire conflict domain classes into ConflictAnalyzerService
flyingrobots Apr 7, 2026
000af13
docs: update cycle 0012 design doc with revised phase numbering
flyingrobots Apr 7, 2026
237d578
refactor: extract ConflictFrameLoader from ConflictAnalyzerService
flyingrobots Apr 7, 2026
753c0e6
refactor: decompose ConflictAnalyzerService into pipeline modules
flyingrobots Apr 7, 2026
8f70d9e
refactor: behavior on owning types, disable no-unsafe-* lint rules
flyingrobots Apr 7, 2026
6cac476
docs: cycle 0012 retro with no-unsafe-* decision record
flyingrobots Apr 7, 2026
0ef2ba8
refactor: strip all @type casts and @typedef blocks from conflict mod…
flyingrobots Apr 7, 2026
ec4226d
refactor: strip sludge from ConflictAnalysisRequest
flyingrobots Apr 7, 2026
5721409
docs: add sludge report to cycle 0012 retro
flyingrobots Apr 7, 2026
78e7790
refactor: clean facade, inline dead wrappers, strip last @import
flyingrobots Apr 7, 2026
1f6f6c0
chore: remove stale eslint-disable directives for disabled no-unsafe-…
flyingrobots Apr 7, 2026
3799eb8
chore: gitignore .mcp.json and .codex/
flyingrobots Apr 7, 2026
5d2e9b3
refactor: remove dead exports from conflict analyzer facade
flyingrobots Apr 7, 2026
36e6501
refactor: remove dead exports from 14 source files
flyingrobots Apr 8, 2026
da2d9de
refactor: remove 10 unused re-exports from errors barrel
flyingrobots Apr 8, 2026
f5a743b
docs: close cycle 0012, record no-unsafe-* policy, file god-context s…
flyingrobots Apr 8, 2026
4ff83c6
chore: graveyard 8 completed ASAP items, file resilience policy idea
flyingrobots Apr 8, 2026
ededf1b
ci: make tsc Gate 1 advisory — JSDoc JS produces false positives
flyingrobots Apr 8, 2026
a1a8148
docs: SYSTEMS_STYLE_TYPESCRIPT.md — the SSTS manifesto
flyingrobots Apr 8, 2026
523443d
docs: cycle 0013 design — TypeScript migration, no gods, no large files
flyingrobots Apr 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ jobs:
node-version: '22'
cache: 'npm'
- run: npm ci
- name: 'Gate 1: TypeScript compiler (strict source mode)'
- name: 'Gate 1: TypeScript compiler (advisory — JSDoc JS produces false positives across module boundaries)'
continue-on-error: true
run: npm run typecheck:src
- name: 'Gate 2: IRONCLAD policy checker (any/wildcard/ts-ignore ban)'
run: npm run typecheck:policy
- name: 'Gate 3: Consumer type surface test'
run: npm run typecheck:consumer
- name: 'Gate 4: ESLint (typed rules + no-explicit-any + no-unsafe-*)'
- name: 'Gate 4: ESLint (typed rules + no-explicit-any)'
run: npm run lint
- name: 'Gate 4b: Lint ratchet (zero-error invariant)'
run: npm run lint:ratchet
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ node_modules/
.DS_Store
.vite/
.claude/
.codex/
.mcp.json
coverage/
CLAUDE.md
TASKS-DO-NOT-CHECK-IN.md
Expand Down
15 changes: 15 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
## Engineering Doctrine

- Read `docs/SYSTEMS_STYLE_JAVASCRIPT.md` before making design-level changes.
- Prefer one file per class, type, or object. If a file accumulates peer concepts, split it.
- Runtime truth wins. If something has invariants, identity, or behavior, it should exist as a runtime-backed type.
- Validate at boundaries and constructors. Constructors establish invariants and do no I/O.
- Prefer `instanceof` dispatch over tag switching.
Expand All @@ -42,6 +43,20 @@
- Hexagonal architecture is mandatory. `src/domain/` does not import host APIs or Node-specific globals.
- Wall clock is banned from `src/domain/`. Time must enter through a port or parameter.
- Domain bytes are `Uint8Array`; `Buffer` stays in infrastructure adapters.
- Public APIs should be heavily JSDoc'd. If a public surface changes, update its JSDoc in the same slice.
- No sludge. Do not leave helper corridors, fake shape trust, or transitional duplication behind at the end of a slice.

## Refactor Gates

- For any refactor slice, touched code must reach `100%` test coverage before the slice is considered done.
- Run an SSJS scorecard on every slice. Until an automated scorecard exists, use a manual checklist and require all green on touched files:
- runtime-backed forms for new concepts
- boundary validation stays at boundaries
- behavior lives on the owning type/module
- no message parsing for behaviorally significant branching
- no ambient time or ambient entropy in domain code
- no fake shape trust or cast-cosplay
- End each substantial slice with a funny progress report that explains what mess we got ourselves into, what mess we got ourselves out of, and what comes next. Battle report style is optional.

## Repo Context

Expand Down
4 changes: 2 additions & 2 deletions bin/cli/commands/debug/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export async function getStrandPatchEntriesForDebug(graph, strandId, lamportCeil
* }
* }}
*/
export function summarizeStrandContextForDebug(strand) {
function summarizeStrandContextForDebug(strand) {
return {
strandId: strand.strandId,
baseLamportCeiling: strand.baseObservation.lamportCeiling,
Expand Down Expand Up @@ -217,7 +217,7 @@ function addIfNonEmptyString(ids, value) {
* @param {DebugOpLike[]|undefined} ops - Raw patch operations
* @returns {string[]} Sorted unique identifiers
*/
export function collectTouchedIds(ops) {
function collectTouchedIds(ops) {
if (!Array.isArray(ops) || ops.length === 0) {
return [];
}
Expand Down
1 change: 0 additions & 1 deletion bin/cli/commands/path.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ async function attachRenderedSvg(payload, view, graphName) {
async function runPathTraversal(ctx, pathOptions) {
const { graph, graphName, view } = ctx;
/** @type {PathResult} */
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment -- traverse.shortestPath is typed as Function in WarpGraphInstance
const result = await graph.traverse.shortestPath(
pathOptions.from,
pathOptions.to,
Expand Down
2 changes: 1 addition & 1 deletion bin/cli/shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export function createHookInstaller() {
* @param {string} key - Git config key (or '--git-dir' for the .git directory)
* @returns {string|null} Config value, or null if not set
*/
export function execGitConfigValue(repoPath, key) {
function execGitConfigValue(repoPath, key) {
try {
if (key === '--git-dir') {
return execFileSync('git', ['-C', repoPath, 'rev-parse', '--git-dir'], {
Expand Down
19 changes: 19 additions & 0 deletions docs/SYSTEMS_STYLE_JAVASCRIPT.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,25 @@ engine.compactPreservingTombstones(log);
- `any` is banned. `unknown` at raw edges only, eliminated immediately.
- Type-only constructs must not create a false sense of safety that the runtime does not back up.

**Disabled type-aware lint rules:**

The `@typescript-eslint/no-unsafe-*` family (`no-unsafe-assignment`,
`no-unsafe-member-access`, `no-unsafe-return`, `no-unsafe-call`) is
**disabled project-wide**. `strict-boolean-expressions` is relaxed to
allow `any` in conditionals.

These rules produce false positives in JSDoc-annotated JavaScript —
tsc loses type information across module boundaries and flags every
cross-module call as unsafe. In a codebase where safety comes from
runtime-backed classes with constructor validation, `instanceof`
dispatch, and `Object.freeze`, the rules add noise without catching
bugs. They also incentivize `@type` cast annotations that paper over
tsc's limitations rather than fixing real problems.

What we keep: `no-explicit-any` (banning `any` in authored annotations),
`switch-exhaustiveness-check`, `only-throw-error`,
`no-unnecessary-type-assertion`, and all non-type-aware rules.

### The Anti-Shape-Soup Doctrine

Most bad JavaScript infrastructure stems from weak modeling. The discipline is:
Expand Down
Loading
Loading