futura-scion 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +148 -0
- package/bin/scion.js +106 -7
- package/knowledge/architecture.yaml +98 -0
- package/knowledge/core.yaml +99 -0
- package/knowledge/git-sdlc.yaml +82 -0
- package/knowledge/javascript.yaml +89 -0
- package/knowledge/performance.yaml +85 -0
- package/knowledge/python.yaml +85 -0
- package/knowledge/security.yaml +97 -0
- package/knowledge/testing.yaml +85 -0
- package/package.json +5 -1
- package/src/brain/conversations.js +84 -0
- package/src/brain/db.js +93 -0
- package/src/brain/memory-graph.js +242 -0
- package/src/brain/memory.js +19 -4
- package/src/config.js +47 -3
- package/src/http.js +333 -0
- package/src/index.js +3 -1
- package/src/kernel/watchdog.js +79 -0
- package/src/mind/calltree-context.js +129 -0
- package/src/mind/completeness.js +163 -0
- package/src/mind/generator.js +9 -1
- package/src/mind/grade.js +184 -0
- package/src/mind/harness-gate.js +235 -0
- package/src/mind/harness-miner.js +196 -0
- package/src/mind/harness-propose.js +163 -0
- package/src/mind/interventions.js +186 -0
- package/src/mind/knowledge.js +165 -0
- package/src/mind/learn-loop.js +204 -0
- package/src/mind/nlu.js +21 -2
- package/src/mind/provider.js +109 -0
- package/src/mind/tools.js +46 -0
- package/src/ui/app.js +392 -0
- package/src/ui/index.html +141 -0
- package/src/ui/style.css +175 -0
- package/src/worker.js +21 -0
package/README.md
CHANGED
|
@@ -617,6 +617,154 @@ default) keeps it fully inert even for tasks that opt in with
|
|
|
617
617
|
`payload.generate: true`. The doctrine is unchanged — the LLM proposes,
|
|
618
618
|
the Gate disposes, the certificate proves it.
|
|
619
619
|
|
|
620
|
+
### Self-improvement — the harness evolves under its own Gate (`scion evolve`)
|
|
621
|
+
|
|
622
|
+
FS applies its verification doctrine to ITSELF. The nightly evolution loop
|
|
623
|
+
(imp_doc adoption, zero-LLM) is: **mine → propose → gate → apply**.
|
|
624
|
+
|
|
625
|
+
- **Weakness miner** — failures from the queue and trail are normalized to
|
|
626
|
+
signature hashes (`failureSignatureOf`); a signature with ≥3 occurrences
|
|
627
|
+
across ≥2 goal families is a HARNESS weakness (not one goal's bad luck),
|
|
628
|
+
classified into the 4-layer taxonomy (environment-contract /
|
|
629
|
+
procedural-skill / action-realization / trajectory-regulation).
|
|
630
|
+
- **Proposals** — deterministic per layer (bounds-field, verifier-recipe,
|
|
631
|
+
tool-filter-rule, spec-note), hard 20-line diff budget, targets must
|
|
632
|
+
exist. No LLM anywhere; a generator can be attached later but is still
|
|
633
|
+
gate-checked.
|
|
634
|
+
- **The harness-edit Gate** — SICA utility scoring
|
|
635
|
+
(`U = 0.5·passRate + 0.25·(1−cost) + 0.25·(1−time)`) over the replay
|
|
636
|
+
window: accept only if utility improves AND pass-rate does not regress.
|
|
637
|
+
Every decision lands in the `harness_edits` audit table; rejected
|
|
638
|
+
edit-hashes are remembered (never re-proposed); bounded to ≤3 accepted
|
|
639
|
+
edits per batch; addressed signatures skip (idempotent). Gate-passing but
|
|
640
|
+
utility-unproven edits ARCHIVE in `harness_variants` for monthly re-scoring
|
|
641
|
+
(`scion evolve variants`) — population thinking, nothing promising is lost.
|
|
642
|
+
|
|
643
|
+
```bash
|
|
644
|
+
scion evolve # one bounded, idempotent batch
|
|
645
|
+
scion evolve --dry-run # mine + propose only
|
|
646
|
+
scion evolve variants # re-score the archive (G4)
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
### Stuck-trajectory watchdog + completeness + grading (the guardrails)
|
|
650
|
+
|
|
651
|
+
- **Watchdog** (`src/kernel/watchdog.js`) — hash consecutive `(action,
|
|
652
|
+
state)` pairs; 3 identical → stuck, abort before burning the bounds.
|
|
653
|
+
Key-order-insensitive, pure, also usable as an audit (`findStuckPoint`).
|
|
654
|
+
- **Completeness** (`src/mind/completeness.js`) — every research bundle now
|
|
655
|
+
carries a deterministic completeness verdict: entity coverage,
|
|
656
|
+
subquestion corroboration (stem-folded), source-quality floor. Incomplete
|
|
657
|
+
results produce gap-targeted `replan_hints` and a bounded replan loop
|
|
658
|
+
(`verifyWithReplan`, ≤2 replans) — the VMAO orchestration-level check.
|
|
659
|
+
- **Run records + grading** (`scion eval`) — every task appends a portable
|
|
660
|
+
JSONL run record to `eval/runs.jsonl` (trajectory, cost, outcome); the
|
|
661
|
+
3-scorer grader (outcome 0.5 / trajectory 0.3 / economy 0.2) emits
|
|
662
|
+
per-run grades and a trend file. `scion eval regression` gates on
|
|
663
|
+
per-family pass-rate drops; `scion eval capability` trends pass-rate per
|
|
664
|
+
difficulty tier.
|
|
665
|
+
|
|
666
|
+
### Graph-linked memory + interventions (the brain connects and travels)
|
|
667
|
+
|
|
668
|
+
- **Memory graph** — every save links into `memory_links`:
|
|
669
|
+
token-overlap → `related` (weight = Jaccard), same family + opposite
|
|
670
|
+
outcome polarity → `contradicts` (the older side ranks lower —
|
|
671
|
+
suppression, never deletion), newer-higher-confidence → `supersedes`.
|
|
672
|
+
Recall does 1-hop expansion (neighbors at ×0.5) and trust ranking:
|
|
673
|
+
gate-verified memories weigh 1.0, observed 0.95, web 0.7, LLM 0.6.
|
|
674
|
+
- **Interventions** (`scion interventions import [dir]`) — accepted harness
|
|
675
|
+
edits export as `interventions/<hash>.intervention.yaml` artifacts
|
|
676
|
+
(signature, layer, edit, evidence, provenance) and import into another
|
|
677
|
+
FS instance ONLY if that instance's own history shows the same failure
|
|
678
|
+
signature ≥2 times: no blind cross-pollination. This is the fleet brain's
|
|
679
|
+
transport format for learned fixes.
|
|
680
|
+
|
|
681
|
+
### Call-tree context + indexed actions (Jev/LLM-as-code discipline)
|
|
682
|
+
|
|
683
|
+
- **Call-tree context** (`src/mind/calltree-context.js`) — the generate
|
|
684
|
+
rung's context is the task's ANCESTOR CHAIN from the trail, each ancestor
|
|
685
|
+
budget-capped by depth (deeper → less), total ≤4000 chars — replacing
|
|
686
|
+
flat truncation. Flat inputs stay backward compatible.
|
|
687
|
+
- **Indexed action space** — clarification options render as numbered
|
|
688
|
+
ACTIONS with executable consequences (`[2] analyze the named file and
|
|
689
|
+
apply a gate-verified fix`); answering `2` is a complete decision.
|
|
690
|
+
- **Pre-execution revalidation** — tool calls re-check freshness before
|
|
691
|
+
spawning: file targets that vanished since the decision refuse loudly
|
|
692
|
+
(`stale decision`) instead of executing into a world that moved.
|
|
693
|
+
|
|
694
|
+
### The learn → build → improve → repeat layer (`scion learn`)
|
|
695
|
+
|
|
696
|
+
The mandate: FS must get BETTER at every kind of problem it takes on —
|
|
697
|
+
software, research, finding things — from its own mistakes, without anyone
|
|
698
|
+
remembering to run a command. This layer is the always-on circulatory
|
|
699
|
+
system connecting every learning organ:
|
|
700
|
+
|
|
701
|
+
- **LEARN** — every task outcome (verified fix, gate failure, escalation,
|
|
702
|
+
error) is observed automatically by the worker and written as a graded
|
|
703
|
+
run record. Failures are the raw material; nothing escapes the loop.
|
|
704
|
+
- **BUILD** — repeated verified fixes forge into seeds (precision-floored);
|
|
705
|
+
clarifications teach the NLU lexicon; interventions export to the fleet.
|
|
706
|
+
- **IMPROVE** — the weakness miner finds recurring failure patterns across
|
|
707
|
+
ALL domains; the harness gate utility-verifies bounded self-edits; the
|
|
708
|
+
variant archive re-scores what didn't win yet.
|
|
709
|
+
- **REPEAT** — every cycle is measured into the `learn_cycles` ledger
|
|
710
|
+
(pass rate, replay hit rate, deterministic share, seeds, edits accepted);
|
|
711
|
+
improvement is a TREND over rows, never a claim.
|
|
712
|
+
|
|
713
|
+
```bash
|
|
714
|
+
scion learn # one full cycle now
|
|
715
|
+
scion learn trend # is FS improving? (ledger-backed, ≥2 cycles)
|
|
716
|
+
scion learn vitals # current vital signs
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
With `learn: { auto: true }` in config, `scion serve` runs a cycle every
|
|
720
|
+
`learn.interval_ms` (default 6h) in-process — the harness improves itself
|
|
721
|
+
while it works. Zero-LLM by construction.
|
|
722
|
+
|
|
723
|
+
### FS Desktop — the standalone UI (chat / agent / plan / architect)
|
|
724
|
+
|
|
725
|
+
FS ships a real UI in two forms, both zero-build:
|
|
726
|
+
|
|
727
|
+
- **Web console (ships in the npm package):** `scion serve` now serves the
|
|
728
|
+
FS Desktop SPA at `http://127.0.0.1:5107/ui` — open it in any browser.
|
|
729
|
+
Nothing extra to install; works over SSH tunnels and on remote machines.
|
|
730
|
+
- **Electron desktop shell (`desktop/`):** a thin host that boots the kernel
|
|
731
|
+
as a child process and renders the same UI in a native window.
|
|
732
|
+
```bash
|
|
733
|
+
npm run desktop # dev (needs: cd desktop && npm install)
|
|
734
|
+
npm run desktop:build # installers (NSIS / DMG / AppImage) via electron-builder
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
**Surfaces** (every action goes through the same kernel routes the CLI and
|
|
738
|
+
MCP use — the UI can never do more than the kernel allows):
|
|
739
|
+
|
|
740
|
+
- **Chat with streaming + history** — replies stream over SSE with live
|
|
741
|
+
NLU/agent progress events; every conversation persists in the brain with a
|
|
742
|
+
sidebar (new / open / rename / delete), auto-titling, and secret redaction
|
|
743
|
+
at write time — history survives restarts and travels with the DB.
|
|
744
|
+
- **Chat mode** — plain language in, state-grounded answers out: status,
|
|
745
|
+
brain/economy/queue lookups, brain search. Deterministic NLU; no LLM.
|
|
746
|
+
- **Agent mode** — real work: your utterance is NLU-interpreted, slotted,
|
|
747
|
+
enqueued, and run through the full ladder→Gate pipeline with a rung+
|
|
748
|
+
certificate summary in the transcript.
|
|
749
|
+
- **Plan mode** — research with tools + the deterministic completeness
|
|
750
|
+
verdict (entity coverage, corroboration, source floor) as evidence.
|
|
751
|
+
- **Architect mode** — one-click declared-architecture scan with violations.
|
|
752
|
+
- **Review queue** — the human gate in the loop: escalations with the
|
|
753
|
+
ladder's last proposal, Approve/Reject/Defer, badge counts live.
|
|
754
|
+
- **Trail / Brain / Economy dashboards** — the journaled decision trail,
|
|
755
|
+
brain stats, and the token-economy report as live views.
|
|
756
|
+
- **Autonomy toggle** — semi-autonomous (default: each agent action asks
|
|
757
|
+
through the Gate + Review flow) vs autonomous (apply directly; the Gate
|
|
758
|
+
still verifies everything, destructive work still escalates).
|
|
759
|
+
|
|
760
|
+
**LLM attach (optional):** Settings → Provider covers Ollama, LM Studio,
|
|
761
|
+
OpenAI, Anthropic, OpenRouter, and any OpenAI-compatible endpoint, with a
|
|
762
|
+
connection test. Saving sets `llm.provider/baseUrl/model/apiKey` +
|
|
763
|
+
`llm.daily_tokens` in config, which arms rung G (the governance-shell
|
|
764
|
+
generator): the model PROPOSES patches, the Gate verifies them by exit code,
|
|
765
|
+
and nothing unverified is learned or shipped. `daily_tokens: 0` keeps FS
|
|
766
|
+
fully deterministic — a local model (Ollama/LM Studio) works offline.
|
|
767
|
+
|
|
620
768
|
### Semi-autonomous auto-fix (`scion watch` + `daemon.auto_fix`)
|
|
621
769
|
|
|
622
770
|
By default the daemon only **detects and remembers**. With `daemon.auto_fix: true`
|
package/bin/scion.js
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { createInterface } from 'node:readline';
|
|
19
19
|
import { existsSync } from 'node:fs';
|
|
20
20
|
import { resolve } from 'node:path';
|
|
21
|
+
import { spawnSync } from 'node:child_process';
|
|
21
22
|
import * as trail from '../src/kernel/trail.js';
|
|
22
23
|
import {
|
|
23
24
|
enqueue, runSwarm, economy, trailList, runTask, claim as claimTask,
|
|
@@ -441,6 +442,54 @@ switch (cmd || '') {
|
|
|
441
442
|
console.log(JSON.stringify({ dry_run: dryRun, ...result }, null, 2));
|
|
442
443
|
break;
|
|
443
444
|
}
|
|
445
|
+
case 'eval': {
|
|
446
|
+
// Portable run records + grading (workstream F):
|
|
447
|
+
// scion eval regression per-family pass-rate drop check (gate-able)
|
|
448
|
+
// scion eval capability pass-rate per difficulty tier (trend only)
|
|
449
|
+
const { regressionCheck, capabilityReport } = await import('../src/mind/grade.js');
|
|
450
|
+
if (arg === 'capability') console.log(JSON.stringify(capabilityReport(), null, 2));
|
|
451
|
+
else console.log(JSON.stringify(regressionCheck(), null, 2));
|
|
452
|
+
const reg = regressionCheck();
|
|
453
|
+
if (arg !== 'capability' && Object.values(reg).some(f => f.ok === false)) process.exitCode = 1;
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
case 'interventions': {
|
|
457
|
+
// Shared failure-intervention library (workstream E):
|
|
458
|
+
// scion interventions import [dir] import artifacts with the local-occurrence floor
|
|
459
|
+
const { importInterventions } = await import('../src/mind/interventions.js');
|
|
460
|
+
const dir = arg && arg !== 'import' ? arg : 'interventions';
|
|
461
|
+
console.log(JSON.stringify(importInterventions(dir), null, 2));
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
case 'learn': {
|
|
465
|
+
// THE learn → build → improve → repeat layer:
|
|
466
|
+
// scion learn one full cycle (mine → gate → forge → rescore → ledger)
|
|
467
|
+
// scion learn trend is FS improving? (ledger-backed, ≥2 cycles)
|
|
468
|
+
// scion learn vitals the current vital signs
|
|
469
|
+
const loop = await import('../src/mind/learn-loop.js');
|
|
470
|
+
if (arg === 'trend') console.log(JSON.stringify(loop.trend(), null, 2));
|
|
471
|
+
else if (arg === 'vitals') console.log(JSON.stringify(loop.vitals(), null, 2));
|
|
472
|
+
else console.log(JSON.stringify(loop.cycle(), null, 2));
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
case 'evolve': {
|
|
476
|
+
// The nightly harness-evolution pass (A4): mine weaknesses → propose
|
|
477
|
+
// harness edits → gate them (SICA utility) → apply the accepted. Bounded
|
|
478
|
+
// (≤3 accepted per batch), idempotent (addressed signatures skip),
|
|
479
|
+
// zero-LLM. `scion evolve --dry-run` mines+proposes but applies nothing.
|
|
480
|
+
// scion evolve one bounded batch
|
|
481
|
+
// scion evolve --dry-run mine + propose only
|
|
482
|
+
// scion evolve variants re-score archived harness variants (G4)
|
|
483
|
+
const hGate = await import('../src/mind/harness-gate.js');
|
|
484
|
+
if (arg === 'variants') {
|
|
485
|
+
console.log(JSON.stringify(hGate.rescoreVariants({}), null, 2));
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
const dryRun = arg === '--dry-run';
|
|
489
|
+
const result = hGate.evolveBatch(dryRun ? { applyAfter: undefined } : {});
|
|
490
|
+
console.log(JSON.stringify({ dry_run: dryRun, ...result }, null, 2));
|
|
491
|
+
break;
|
|
492
|
+
}
|
|
444
493
|
case 'recipes': {
|
|
445
494
|
// The recipe library: gate verifier bundles per stack.
|
|
446
495
|
// scion recipes list the library
|
|
@@ -565,9 +614,21 @@ switch (cmd || '') {
|
|
|
565
614
|
// scion conventions <file> deviations of one file (evidence rows)
|
|
566
615
|
const c = await import('../src/mind/conventions.js');
|
|
567
616
|
if (arg && !arg.startsWith('--')) {
|
|
568
|
-
const { readFileSync } = await import('node:fs');
|
|
569
|
-
|
|
570
|
-
|
|
617
|
+
const { readFileSync, statSync } = await import('node:fs');
|
|
618
|
+
let st = null;
|
|
619
|
+
try { st = statSync(arg); } catch { /* handled below */ }
|
|
620
|
+
if (st?.isDirectory()) {
|
|
621
|
+
// A directory argument means: discover + persist over that tree.
|
|
622
|
+
const result = c.discoverConventions(arg);
|
|
623
|
+
c.saveConventions(result);
|
|
624
|
+
console.log(JSON.stringify({ ok: true, files: result.files, conventions: result.conventions }, null, 2));
|
|
625
|
+
} else if (st?.isFile()) {
|
|
626
|
+
const source = readFileSync(arg, 'utf8');
|
|
627
|
+
console.log(JSON.stringify({ file: arg, deviations: c.deviationsFor(source) }, null, 2));
|
|
628
|
+
} else {
|
|
629
|
+
console.error(`conventions: no such file or directory: ${arg}`);
|
|
630
|
+
process.exitCode = 1;
|
|
631
|
+
}
|
|
571
632
|
} else {
|
|
572
633
|
const result = c.discoverConventions(arg && arg !== '--all' ? arg : 'src');
|
|
573
634
|
c.saveConventions(result);
|
|
@@ -641,11 +702,35 @@ switch (cmd || '') {
|
|
|
641
702
|
});
|
|
642
703
|
const api = await startApi({ port: Number(arg) || undefined, leader });
|
|
643
704
|
leader.start();
|
|
705
|
+
// FS Desktop support: provider-backed generator (rung G) from config,
|
|
706
|
+
// and the default agent-mode runTask over the real oracle.
|
|
707
|
+
const { makeGenerator } = await import('../src/mind/provider.js');
|
|
708
|
+
const { configureLlm } = await import('../src/ladder.js');
|
|
709
|
+
const generator = makeGenerator(cfg.llm);
|
|
710
|
+
configureLlm({ generator, daily_tokens: cfg.llm?.daily_tokens ?? 0 });
|
|
711
|
+
const { setRunTask } = await import('../src/http.js');
|
|
712
|
+
setRunTask(async (task) => runTask(claimTask('ui', task.id), oracle));
|
|
713
|
+
// The always-on learn→build→improve→repeat layer (config learn.auto).
|
|
714
|
+
if (cfg.learn?.auto) {
|
|
715
|
+
const { startAuto } = await import('../src/mind/learn-loop.js');
|
|
716
|
+
startAuto();
|
|
717
|
+
console.log(` learn-loop: auto-cycle every ${Math.round((cfg.learn.interval_ms ?? 21600000) / 60000)} min`);
|
|
718
|
+
}
|
|
644
719
|
// Observability (env-gated): OTLP log export + ntfy push.
|
|
645
720
|
const { startObservers } = await import('../src/kernel/observe.js');
|
|
646
721
|
startObservers();
|
|
647
722
|
console.log(`scion serve: http://127.0.0.1:${api.port} role=${leader.role}${leader.primaryUrl ? ` primary=${leader.primaryUrl}` : ''} (SCION_TOKEN guards routes when set)`);
|
|
648
|
-
console.log(
|
|
723
|
+
console.log(` UI: http://127.0.0.1:${api.port}/ui ← FS Desktop (chat, agent, dashboards)`);
|
|
724
|
+
console.log(' flags: --follower --lease-ms N --leader-poll-ms N --primary-url URL [--open]');
|
|
725
|
+
// --open: launch the default browser at the UI (best-effort, every OS).
|
|
726
|
+
if (process.argv.includes('--open')) {
|
|
727
|
+
const { spawn } = await import('node:child_process');
|
|
728
|
+
const url = `http://127.0.0.1:${api.port}/ui`;
|
|
729
|
+
const opener = process.platform === 'win32' ? spawn('cmd', ['/c', 'start', '', url], { detached: true, stdio: 'ignore' })
|
|
730
|
+
: process.platform === 'darwin' ? spawn('open', [url], { detached: true, stdio: 'ignore' })
|
|
731
|
+
: spawn('xdg-open', [url], { detached: true, stdio: 'ignore' });
|
|
732
|
+
opener.unref();
|
|
733
|
+
}
|
|
649
734
|
const sweep = setInterval(() => {
|
|
650
735
|
try { dailyMaintenance(); } catch { /* maintenance never kills the server */ }
|
|
651
736
|
}, 60_000);
|
|
@@ -659,6 +744,16 @@ switch (cmd || '') {
|
|
|
659
744
|
}
|
|
660
745
|
break;
|
|
661
746
|
}
|
|
747
|
+
case 'ui': {
|
|
748
|
+
// `scion ui` — the one-command desktop experience: serve + open the UI.
|
|
749
|
+
// Identical to `scion serve --open`; a separate word because that's what
|
|
750
|
+
// people type after `npm i -g futura-scion`.
|
|
751
|
+
const self = process.argv[1];
|
|
752
|
+
const rest = process.argv.slice(2).filter(a => a !== 'ui');
|
|
753
|
+
const r = spawnSync(process.execPath, [self, 'serve', ...rest, '--open'], { stdio: 'inherit', env: process.env });
|
|
754
|
+
process.exitCode = r.status ?? 0;
|
|
755
|
+
break;
|
|
756
|
+
}
|
|
662
757
|
case 'remote': {
|
|
663
758
|
// Distributed tier: drain a remote scion's queue from THIS machine.
|
|
664
759
|
// scion remote --url http://host:5107 --workerId rw-1 [--max N] [--token T]
|
|
@@ -687,9 +782,13 @@ switch (cmd || '') {
|
|
|
687
782
|
}
|
|
688
783
|
case 'dash': {
|
|
689
784
|
// Live TUI dashboard — one ANSI refresh loop over kernel state.
|
|
785
|
+
// `scion dash <frames> <intervalMs>` runs N frames then exits (CI/trial
|
|
786
|
+
// friendly); bare `scion dash` loops until Ctrl+C as before.
|
|
690
787
|
const { runDashboard } = await import('../src/kernel/dash.js');
|
|
691
|
-
const
|
|
692
|
-
|
|
788
|
+
const nums = [arg, ...restArgs].filter(a => /^\d+$/.test(a)).map(Number);
|
|
789
|
+
const frames = nums[0] ?? null;
|
|
790
|
+
const intervalMs = nums[1] ?? 2000;
|
|
791
|
+
await runDashboard({ intervalMs, ...(frames ? { maxFrames: frames } : {}) });
|
|
693
792
|
break;
|
|
694
793
|
}
|
|
695
794
|
case 'mcp': {
|
|
@@ -778,6 +877,6 @@ switch (cmd || '') {
|
|
|
778
877
|
break;
|
|
779
878
|
}
|
|
780
879
|
default:
|
|
781
|
-
console.error(`unknown command: ${cmd}\nusage: scion [run "<task>" | swarm [n] | plan <target> [--out m.json] [--run] | workflow <manifest.json> | analyze [dir] | fix <file> | watch [dir] [--auto-fix] [--concurrency N] | economy | brain | remember "<c>" | search "<q>" | reason "<topic>" | forge [--dry-run] | review [-i] | resolve <id> approve "<fix>"|reject|defer | gaps [teach <id> <intent> | forget <id> | --all] | scopes [list|add <name>|rm <name>] | serve [port] [--follower --lease-ms N --leader-poll-ms N --primary-url URL] | remote --url URL --workerId ID | leader | recipes [doctor | show <name>]`);
|
|
880
|
+
console.error(`unknown command: ${cmd}\nusage: scion [run "<task>" | swarm [n] | plan <target> [--out m.json] [--run] | workflow <manifest.json> | analyze [dir] | fix <file> | watch [dir] [--auto-fix] [--concurrency N] | economy | brain | remember "<c>" | search "<q>" | reason "<topic>" | forge [--dry-run] | review [-i] | resolve <id> approve "<fix>"|reject|defer | gaps [teach <id> <intent> | forget <id> | --all] | scopes [list|add <name>|rm <name>] | ui | serve [port] [--follower --lease-ms N --leader-poll-ms N --primary-url URL] | remote --url URL --workerId ID | leader | recipes [doctor | show <name>]`);
|
|
782
881
|
process.exitCode = 1;
|
|
783
882
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# knowledge/architecture.yaml — software architecture and design knowledge.
|
|
2
|
+
pack: architecture-design
|
|
3
|
+
description: Architecture discipline — coupling, boundaries, dependency direction, design trade-offs
|
|
4
|
+
entries:
|
|
5
|
+
- title: Dependencies point from volatile to stable
|
|
6
|
+
type: principle
|
|
7
|
+
importance: 9
|
|
8
|
+
tags: [architecture, dependencies]
|
|
9
|
+
content: >
|
|
10
|
+
The most stable abstractions (domain concepts, interfaces) should be
|
|
11
|
+
imported BY the most volatile ones (UI, infrastructure, adapters) —
|
|
12
|
+
never the reverse. When infrastructure dictates domain shape, every
|
|
13
|
+
database or framework change ripples into business logic. Source:
|
|
14
|
+
stable-dependencies principle, hexagonal architecture (Cockburn),
|
|
15
|
+
clean architecture (Martin).
|
|
16
|
+
- title: Coupling is about knowledge, not syntax
|
|
17
|
+
type: principle
|
|
18
|
+
importance: 8
|
|
19
|
+
tags: [architecture, coupling]
|
|
20
|
+
content: >
|
|
21
|
+
Two modules are coupled when a change in one forces a change in the
|
|
22
|
+
other. Sharing a database table, an implicit file format, or a timing
|
|
23
|
+
assumption couples more tightly than an explicit interface call.
|
|
24
|
+
Reduce shared knowledge before reducing call counts. Source: Parnas
|
|
25
|
+
information hiding, Connascence (Meilir Page-Jones).
|
|
26
|
+
- title: Boundaries earn their cost by isolating change
|
|
27
|
+
type: principle
|
|
28
|
+
importance: 8
|
|
29
|
+
tags: [architecture, boundaries, microservices]
|
|
30
|
+
content: >
|
|
31
|
+
Every boundary (module, service, team) has a real cost: serialization,
|
|
32
|
+
versioning, network failure, coordination. A boundary pays for itself
|
|
33
|
+
only where change frequency or failure isolation demands it. Uniform
|
|
34
|
+
micro-decomposition is a tax paid everywhere for benefits realized
|
|
35
|
+
somewhere. Source: Monolith-to-Microservices (Fowler), Saša Ćurčić
|
|
36
|
+
critique lineage.
|
|
37
|
+
- title: Contracts at boundaries — versioned, explicit, backward-aware
|
|
38
|
+
type: principle
|
|
39
|
+
importance: 8
|
|
40
|
+
tags: [api, versioning]
|
|
41
|
+
content: >
|
|
42
|
+
Any interface another party codes against (API, schema, event) is a
|
|
43
|
+
contract: add fields additively, never reinterpret existing fields,
|
|
44
|
+
deprecate before removal, and version when breaking. Implicit
|
|
45
|
+
contracts (undocumented JSON shapes) break at the worst time — in
|
|
46
|
+
production, in another team's code. Source: API design practice,
|
|
47
|
+
Postel-informed evolution guidance.
|
|
48
|
+
- title: Idempotency and retries are partners
|
|
49
|
+
type: principle
|
|
50
|
+
importance: 8
|
|
51
|
+
tags: [distributed, reliability]
|
|
52
|
+
content: >
|
|
53
|
+
A retry without idempotency multiplies effects (double charge, double
|
|
54
|
+
email); an idempotent operation without retries wastes its own safety.
|
|
55
|
+
Design write operations to be safely repeatable (idempotency keys,
|
|
56
|
+
conditional updates) before adding automatic retry logic. Source:
|
|
57
|
+
distributed-systems practice, AWS/Google API guidance.
|
|
58
|
+
- title: Caching invalidates — plan expiry before performance
|
|
59
|
+
type: principle
|
|
60
|
+
importance: 8
|
|
61
|
+
tags: [caching, performance]
|
|
62
|
+
content: >
|
|
63
|
+
A cache is a correctness trade dressed as an optimization: every cache
|
|
64
|
+
needs an invalidation story (TTL, explicit bust, event-driven) and a
|
|
65
|
+
staleness budget the business accepts. Two hard problems (naming,
|
|
66
|
+
cache invalidation) — the second one causes outages. Source: Kahle's
|
|
67
|
+
aphorism lineage, cache practice.
|
|
68
|
+
- title: Data outlives code — schema evolution is the long game
|
|
69
|
+
type: principle
|
|
70
|
+
importance: 8
|
|
71
|
+
tags: [database, schema]
|
|
72
|
+
content: >
|
|
73
|
+
Applications are replaced; databases persist. Design migrations as
|
|
74
|
+
expand → migrate → contract (never in-place breaking changes), keep
|
|
75
|
+
constraints in the database (the last line of defense), and treat
|
|
76
|
+
backfills as explicit, resumable jobs. Source: evolutionary database
|
|
77
|
+
design, live-migration practice.
|
|
78
|
+
- title: Make illegal states unrepresentable
|
|
79
|
+
type: principle
|
|
80
|
+
importance: 8
|
|
81
|
+
tags: [modeling, types]
|
|
82
|
+
content: >
|
|
83
|
+
Model domains so impossible combinations cannot be constructed:
|
|
84
|
+
sum types/unions over boolean flags, constructors that establish
|
|
85
|
+
invariants over bare structs. Defense shifts from runtime checks
|
|
86
|
+
everywhere to construction-time guarantees in one place. Source:
|
|
87
|
+
type-driven design (Yaron Minsky lineage), algebraic data types.
|
|
88
|
+
- title: Concurrency design — shared mutable state is the enemy
|
|
89
|
+
type: principle
|
|
90
|
+
importance: 8
|
|
91
|
+
tags: [concurrency]
|
|
92
|
+
content: >
|
|
93
|
+
Races, deadlocks, and lost updates all require shared mutable state
|
|
94
|
+
reached by multiple actors. Prefer immutable data, message passing,
|
|
95
|
+
or single-owner designs; when sharing is unavoidable, define the
|
|
96
|
+
locking discipline once and document it — ad-hoc locking is a race
|
|
97
|
+
with a delay timer. Source: Hoare CSP, Java Concurrency in Practice
|
|
98
|
+
(Goetz), actor-model lineage.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# knowledge/core.yaml — the discipline's foundational principles.
|
|
2
|
+
# Loaded into the reserved knowledge:core brain slice; consulted by recall
|
|
3
|
+
# and the reasoner across every project. Data, not code — the Gate and the
|
|
4
|
+
# analyzer never act on these; they inform judgment.
|
|
5
|
+
pack: core-principles
|
|
6
|
+
description: Foundational software engineering principles (source-attributed consensus)
|
|
7
|
+
entries:
|
|
8
|
+
- title: Make change small and reversible
|
|
9
|
+
type: principle
|
|
10
|
+
importance: 9
|
|
11
|
+
tags: [change, review, risk]
|
|
12
|
+
content: >
|
|
13
|
+
Small, reversible changes fail cheaply and succeed verifiably. Large
|
|
14
|
+
changes hide defects behind review volume and make rollback impossible.
|
|
15
|
+
Decompose work into commits/PRs that can be understood, verified, and
|
|
16
|
+
reverted independently. Source: industry review-practice consensus.
|
|
17
|
+
- title: Verify behavior with executable checks, never intent
|
|
18
|
+
type: principle
|
|
19
|
+
importance: 10
|
|
20
|
+
tags: [testing, verification, gate]
|
|
21
|
+
content: >
|
|
22
|
+
A change is done when an executable check proves it — test, typecheck,
|
|
23
|
+
lint, or runtime assertion with a real exit code. "Should work" is not
|
|
24
|
+
a state; verification is the only truth source. Source: test-driven
|
|
25
|
+
development lineage (Beck), continuous delivery (Humble/Farley).
|
|
26
|
+
- title: Fail fast, fail loud
|
|
27
|
+
type: principle
|
|
28
|
+
importance: 9
|
|
29
|
+
tags: [errors, reliability]
|
|
30
|
+
content: >
|
|
31
|
+
Surface failure at the earliest possible moment with the fullest
|
|
32
|
+
possible context. Swallowed errors, silent defaults, and late crashes
|
|
33
|
+
multiply debugging cost. An error thrown at the boundary with context
|
|
34
|
+
is cheaper than one discovered downstream. Source: fail-fast design
|
|
35
|
+
(Fowler), defensive programming practice.
|
|
36
|
+
- title: The parser is the contract
|
|
37
|
+
type: principle
|
|
38
|
+
importance: 8
|
|
39
|
+
tags: [boundaries, data, robustness]
|
|
40
|
+
content: >
|
|
41
|
+
Every untrusted input crosses a parse boundary: validate shape, type,
|
|
42
|
+
and range at the edge, then trust the parsed value inside. Validating
|
|
43
|
+
lazily throughout the codebase guarantees gaps. Source: Postel's law
|
|
44
|
+
critiques, parse-don't-validate (Pingala/Alexis King lineage).
|
|
45
|
+
- title: Optimize for reading, secondarily for writing
|
|
46
|
+
type: principle
|
|
47
|
+
importance: 9
|
|
48
|
+
tags: [readability, maintenance]
|
|
49
|
+
content: >
|
|
50
|
+
Code is read far more often than written. Clear names, small functions,
|
|
51
|
+
obvious control flow beat cleverness. The cost of writing is paid once;
|
|
52
|
+
the cost of reading is paid for the code's lifetime. Source: The
|
|
53
|
+
Elements of Programming Style (Kernighan/Plauger), Clean Code debates.
|
|
54
|
+
- title: Measure before optimizing
|
|
55
|
+
type: principle
|
|
56
|
+
importance: 9
|
|
57
|
+
tags: [performance]
|
|
58
|
+
content: >
|
|
59
|
+
Intuition about hot paths is unreliable; profile first, optimize the
|
|
60
|
+
measured bottleneck, and re-measure. Premature optimization trades
|
|
61
|
+
clarity for unproven speed. Keep the simple version until evidence
|
|
62
|
+
demands otherwise. Source: Knuth's full warning, production profiling
|
|
63
|
+
practice.
|
|
64
|
+
- title: Design for the data you have, not the data you wish for
|
|
65
|
+
type: principle
|
|
66
|
+
importance: 8
|
|
67
|
+
tags: [modeling, schema]
|
|
68
|
+
content: >
|
|
69
|
+
Schema and model design should reflect observed reality and honest
|
|
70
|
+
constraints. Speculative generality (unused flags, hypothetical
|
|
71
|
+
entities) is dead weight; missing constraints are future corruption.
|
|
72
|
+
Source: YAGNI (XP), data modeling practice.
|
|
73
|
+
- title: Separation of concerns by responsibility, not by layer worship
|
|
74
|
+
type: principle
|
|
75
|
+
importance: 8
|
|
76
|
+
tags: [architecture, structure]
|
|
77
|
+
content: >
|
|
78
|
+
Divide code so each unit has one reason to change (single responsibility)
|
|
79
|
+
and dependencies point from volatile to stable. Layers are tools, not
|
|
80
|
+
rituals — an anemic layer structure that passes everything through adds
|
|
81
|
+
cost without isolation. Source: SOLID (Martin), stable-dependencies
|
|
82
|
+
principle.
|
|
83
|
+
- title: Automate the repeated, document the decided
|
|
84
|
+
type: principle
|
|
85
|
+
importance: 8
|
|
86
|
+
tags: [automation, docs, process]
|
|
87
|
+
content: >
|
|
88
|
+
Anything done twice by hand becomes a script; anything decided twice
|
|
89
|
+
becomes a written decision record. Humans are for judgment, machines
|
|
90
|
+
for repetition. Source: continuous-delivery practice, ADR lineage.
|
|
91
|
+
- title: Security is a property of the whole pipeline
|
|
92
|
+
type: principle
|
|
93
|
+
importance: 9
|
|
94
|
+
tags: [security]
|
|
95
|
+
content: >
|
|
96
|
+
Trust boundaries, least privilege, and secret handling must hold at
|
|
97
|
+
every layer — dependencies, build, runtime, transport. A strong lock
|
|
98
|
+
on a door that is never closed is not security. Source: defense in
|
|
99
|
+
depth, secure-by-default practice.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# knowledge/git-sdlc.yaml — version control and software delivery lifecycle knowledge.
|
|
2
|
+
pack: git-sdlc
|
|
3
|
+
description: Git discipline, branching, commit hygiene, code review, and delivery flow
|
|
4
|
+
entries:
|
|
5
|
+
- title: Commits are the unit of meaning — atomic, described, intentional
|
|
6
|
+
type: principle
|
|
7
|
+
importance: 8
|
|
8
|
+
tags: [git, commits]
|
|
9
|
+
content: >
|
|
10
|
+
One logical change per commit, with a message that says WHY (the subject
|
|
11
|
+
what, the body why). Mixed concerns ("refactor + fix + new feature") are
|
|
12
|
+
unreviewable and un-bisectable. git bisect only works on a history of
|
|
13
|
+
meaningful units. Source: git-workflow consensus, bisect practice.
|
|
14
|
+
- title: Branching serves integration, not isolation theater
|
|
15
|
+
type: principle
|
|
16
|
+
importance: 8
|
|
17
|
+
tags: [git, branching]
|
|
18
|
+
content: >
|
|
19
|
+
Long-lived branches accumulate merge debt and integration surprise;
|
|
20
|
+
trunk-based development with short-lived branches (hours to days) keeps
|
|
21
|
+
integration continuous. Feature flags decouple deployment from release
|
|
22
|
+
so incomplete work can integrate safely. Source: trunk-based
|
|
23
|
+
development, continuous-delivery lineage.
|
|
24
|
+
- title: Main is always releasable — the gate protects it
|
|
25
|
+
type: principle
|
|
26
|
+
importance: 9
|
|
27
|
+
tags: [git, ci, process]
|
|
28
|
+
content: >
|
|
29
|
+
The main branch passes the full verification pipeline at all times;
|
|
30
|
+
integration happens through gated merges (CI green, review approved).
|
|
31
|
+
A red main stops the entire team — reverting a broken change beats
|
|
32
|
+
debugging it in place. Source: continuous-integration canon.
|
|
33
|
+
- title: Rebase your work, merge the integration, never rewrite shared history
|
|
34
|
+
type: principle
|
|
35
|
+
importance: 8
|
|
36
|
+
tags: [git, history]
|
|
37
|
+
content: >
|
|
38
|
+
Local/unpushed commits: rebase for a clean, linear story. Published
|
|
39
|
+
shared branches: merge (or rebase only with team protocol) — rewriting
|
|
40
|
+
history others built on destroys their work and trust. Force-push to
|
|
41
|
+
shared branches is a destructive act gated by review. Source: git
|
|
42
|
+
workflow documentation, team practice.
|
|
43
|
+
- title: Code review reviews the change, the reviewer owns nothing
|
|
44
|
+
type: principle
|
|
45
|
+
importance: 8
|
|
46
|
+
tags: [process, review]
|
|
47
|
+
content: >
|
|
48
|
+
Review verifies correctness, tests, security, and comprehension by
|
|
49
|
+
someone other than the author. It is bounded: small diffs get real
|
|
50
|
+
review, huge diffs get rubber stamps. Authorial intent (what and why in
|
|
51
|
+
the description) is review input, not archaeology. Blocking comments
|
|
52
|
+
are about the code, never the person. Source: code-review research
|
|
53
|
+
(Bacchelli/Bird), Google engineering practice.
|
|
54
|
+
- title: Semver is a promise — break it explicitly
|
|
55
|
+
type: principle
|
|
56
|
+
importance: 8
|
|
57
|
+
tags: [versioning, release]
|
|
58
|
+
content: >
|
|
59
|
+
MAJOR.MINOR.PATCH encodes compatibility: breaking changes bump MAJOR,
|
|
60
|
+
additive features MINOR, fixes PATCH. Consumers pin ranges accordingly;
|
|
61
|
+
silent breaking changes in minors destroy downstream trust. Changelogs
|
|
62
|
+
and deprecation windows make upgrades plannable. Source: semver.org,
|
|
63
|
+
ecosystem release practice.
|
|
64
|
+
- title: Definition of done includes the boring guarantees
|
|
65
|
+
type: principle
|
|
66
|
+
importance: 8
|
|
67
|
+
tags: [process, quality]
|
|
68
|
+
content: >
|
|
69
|
+
Done means: tests pass, docs updated, observability present (logs/
|
|
70
|
+
metrics for new behavior), secrets absent, migration reversible,
|
|
71
|
+
rollback known. "Works on my machine" is the definition of not-done.
|
|
72
|
+
Source: definition-of-done practice (XP/Scrum lineage).
|
|
73
|
+
- title: Incidents are learning systems — blameless postmortems
|
|
74
|
+
type: principle
|
|
75
|
+
importance: 8
|
|
76
|
+
tags: [operations, incidents]
|
|
77
|
+
content: >
|
|
78
|
+
Postmortems assume everyone acted reasonably with the information they
|
|
79
|
+
had; the analysis targets systemic causes (missing guardrail, ambiguous
|
|
80
|
+
dashboard, absent test), not culprits. Every incident yields concrete
|
|
81
|
+
follow-ups with owners and dates — otherwise it recurs. Source:
|
|
82
|
+
blameless-postmortem practice (US FAA lineage, Google SRE).
|