@sabaiway/agent-workflow-kit 14.19.0 → 14.19.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/CHANGELOG.md CHANGED
@@ -4,6 +4,14 @@ Semantically versioned ([semver](https://semver.org)), newest first. The `versio
4
4
  is the current release. `upgrade` mode reads a project's `docs/ai/.workflow-version` and applies
5
5
  every `migrations/<version>-<slug>.md` newer than it, in semver order.
6
6
 
7
+ ## 14.19.1 — the ADR navigator stamps a cap it honours (AD-167)
8
+
9
+ `references/scripts/archive-decisions.mjs` and its test: byte-identical to memory 8.1.3. `--write-navigator` stamps
10
+ `maxLines` 200 while `docs/ai/adr/log.md` fits and the navigator's own line count past it, so a navigator past 200
11
+ lines no longer fails the docs gate. An upgrade keeps a project's deployed `scripts/archive-decisions.mjs` byte for
12
+ byte: a project already on the ADR store copies `archive-decisions.mjs` and `archive-decisions.test.mjs` from the
13
+ kit's `references/scripts/` into its `scripts/`, then runs `--write-navigator` once. Nothing else in the kit changed.
14
+
7
15
  ## 14.19.0 — the Jev key the vendor's way: `jev-connect` claims no connection, names one restart step and saves for fish and Windows; the guide and the Recommendations item say where to run it (AD-166)
8
16
 
9
17
  **`jev-connect` no longer prints `connected`.** A saved key reaches the agent only once the agent's environment is read
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: agent-workflow-kit
3
3
  description: Deploy or upgrade a portable AI-agent memory-and-workflow system in any project. Use when the user wants to bootstrap `docs/ai/` + an entry-point `AGENTS.md` (+ `CLAUDE.md` alias) + cap/archive/index enforcement in a new or existing repo, set up the Memory Map and session protocols, install the docs-rotation pre-commit hook, or run `/agent-workflow-kit` / `/agent-workflow-kit upgrade`. Triggers on phrases like "set up the memory system", "deploy the AI workflow here", "bootstrap docs/ai", "upgrade the workflow". New to the epic, story and task tier? Run `/agent-workflow-kit tier`. A typed decision with a confidence from Jev? Run `/agent-workflow-kit jev`.
4
4
  disable-model-invocation: true
5
5
  metadata:
6
- version: '14.19.0'
6
+ version: '14.19.1'
7
7
  ---
8
8
 
9
9
  # agent-workflow-kit
package/capability.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "schema": 1,
4
4
  "name": "agent-workflow-kit",
5
5
  "kind": "composition-root",
6
- "version": "14.19.0",
6
+ "version": "14.19.1",
7
7
  "provides": [],
8
8
  "roles": {},
9
9
  "detect": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sabaiway/agent-workflow-kit",
3
- "version": "14.19.0",
3
+ "version": "14.19.1",
4
4
  "description": "Portable, cross-agent memory & workflow for AI coding agents — Claude Code, Codex, Cursor, Devin Desktop. One command deploys an AGENTS.md entry point + docs/ai context with cap/archive/index enforcement into any repo.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -2,7 +2,7 @@
2
2
  // One-file-per-ADR store for docs/ai/decisions.md (ADRs) — the durable replacement for the retired
3
3
  // 3-tier cascade (HOT → WARM archive → a single COLD monolith whose cap was raised release after
4
4
  // release). Every ADR beyond the HOT window becomes its OWN immutable record so no artifact is ever
5
- // O(n) and no cap is ever raised again.
5
+ // O(n) and no cap is raised by hand again (the navigator stamps its own count past 200).
6
6
  //
7
7
  // HOT (docs/ai/decisions.md) — the active ADR window (newest at the bottom), self-bounding
8
8
  // under its own frontmatter maxLines.
@@ -95,7 +95,8 @@ export const ADR_DIR_REL = 'docs/ai/adr';
95
95
  export const NAV_REL = 'docs/ai/adr/log.md';
96
96
 
97
97
  // A per-record cap (generous vs the largest real ADR ~74 lines; a body over it is a genuine smell) and
98
- // the navigator cap (bounded — exceeding it is the future plateau-shard trigger, Decision 8).
98
+ // the navigator's FLOOR: the navigator stamps 200 while it fits and its own line count past it, since
99
+ // nothing rotates a governing row out (docs/ai/specs/memory/adr-navigator.md).
99
100
  export const RECORD_CAP = 400;
100
101
  export const NAV_MAXLINES = 200;
101
102
  // How many most-recent ids the navigator's recent window carries (status-annotated, incl. supersessions).
@@ -701,8 +702,8 @@ export const computeGoverningIds = (entries) => {
701
702
  return new Set(entries.filter((e) => e.status === IN_FORCE_STATUS && !superseded.has(e.id)).map((e) => e.id));
702
703
  };
703
704
 
704
- const NAV_FRONTMATTER = (today) =>
705
- `---\ntype: reference\nlastUpdated: ${today}\nscope: permanent\nstaleAfter: never\nowner: none\nmaxLines: ${NAV_MAXLINES}\n---\n`;
705
+ const NAV_FRONTMATTER = (today, cap) =>
706
+ `---\ntype: reference\nlastUpdated: ${today}\nscope: permanent\nstaleAfter: never\nowner: none\nmaxLines: ${cap}\n---\n`;
706
707
 
707
708
  // Build docs/ai/adr/log.md from the WHOLE corpus (HOT entries ∪ adr/ records). Governing heads
708
709
  // (accepted ∧ not-superseded) sorted newest-first; superseded ADRs drop OUT (still reachable by
@@ -744,7 +745,9 @@ export const buildNavigator = (corpus, today) => {
744
745
  '',
745
746
  ...recent,
746
747
  ].join('\n');
747
- return `${NAV_FRONTMATTER(today)}\n${body}\n`;
748
+ // The cap sits on one line whatever its value, so the count with the floor is the final count.
749
+ const count = lineCountOf(`${NAV_FRONTMATTER(today, NAV_MAXLINES)}\n${body}\n`);
750
+ return `${NAV_FRONTMATTER(today, Math.max(NAV_MAXLINES, count))}\n${body}\n`;
748
751
  };
749
752
 
750
753
  // ── snapshot (durable, pre-delete — Decision 5) ─────────────────────────────────────────
@@ -800,6 +800,47 @@ describe('1.5 navigator — governing heads (computed), superseded drop out but
800
800
  });
801
801
  });
802
802
 
803
+ // ── the navigator's stamped cap (docs/ai/specs/memory/adr-navigator.md) ─────────────────
804
+ //
805
+ // The frame is 38 lines (15 ADRs or more), so 162 governing heads make exactly 200, 163 make 201 and 170 make 208.
806
+
807
+ const capOf = (text) => Number(text.match(/^maxLines: (\d+)$/m)[1]);
808
+ const corpusOf = (n) =>
809
+ Array.from({ length: n }, (_, i) => {
810
+ const id = String(i + 1).padStart(3, '0');
811
+ return { id, idNum: i + 1, title: `T${id}`, status: 'accepted', supersedes: [], supersededBy: [], fileName: `AD-${id}-t.md` };
812
+ });
813
+
814
+ describe('the navigator stamps a cap it honours', () => {
815
+ it('200 while it fits, its own line count past it', () => {
816
+ // spec:adr-navigator/S1
817
+ for (const heads of [2, 162]) {
818
+ const nav = buildNavigator(corpusOf(heads), '2026-07-09');
819
+ assert.equal(capOf(nav), 200, `${heads} heads keep the 200 floor`);
820
+ }
821
+ assert.equal(lineCountOf(buildNavigator(corpusOf(162), '2026-07-09')), 200);
822
+ // 165 entries, two superseded: 163 heads, 201 lines — a stamp from the entry count would read 203.
823
+ const corpus = corpusOf(165).map((e, i) => (i < 2 ? { ...e, supersededBy: ['003'] } : e));
824
+ const big = buildNavigator(corpus, '2026-07-09');
825
+ assert.equal(lineCountOf(big), 201);
826
+ assert.equal(capOf(big), 201, 'past the floor the stamp is the file\'s own count');
827
+ });
828
+
829
+ it('a written navigator past 200 lines fits its cap, --check is green, a hand-edited cap is stale', () => {
830
+ // spec:adr-navigator/S2
831
+ const root = makeRoot();
832
+ seedMigrated(root, { hotIds: ['901'], storeIds: corpusOf(169).map((e) => e.id) });
833
+ const nav = readFileSync(join(root, NAV_REL), 'utf8');
834
+ assert.ok(lineCountOf(nav) > 200, 'the fixture is past the floor');
835
+ assert.ok(lineCountOf(nav) <= capOf(nav), 'the docs gate accepts the written navigator');
836
+ assert.equal(run(['--check', '--today=2026-07-09'], root).code, 0);
837
+ writeFileSync(join(root, NAV_REL), nav.replace(/^maxLines: \d+$/m, 'maxLines: 999'));
838
+ const stale = run(['--check', '--today=2026-07-09'], root);
839
+ assert.equal(stale.code, 1);
840
+ assert.match(stale.errText, /log\.md is stale/);
841
+ });
842
+ });
843
+
803
844
  // ── item (h) degrade branches on the REAL default regenerator (no injection) ───────────
804
845
 
805
846
  describe('defaultRegenerateIndex — loud-degrade branches', () => {