paqad-ai 1.41.1 → 1.43.0
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 +23 -0
- package/README.md +17 -11
- package/dist/cli/index.js +63 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/context/tokenizer-cache.d.ts +18 -0
- package/dist/context/tokenizer-cache.js +42 -0
- package/dist/context/tokenizer-cache.js.map +1 -0
- package/dist/{feature-development-policy-CTmYgPS5.d.ts → feature-development-policy-CeD5nYnf.d.ts} +2 -0
- package/dist/index.d.ts +13 -20
- package/dist/index.js +53 -7
- package/dist/index.js.map +1 -1
- package/dist/kernel/gate.js +13 -2
- package/dist/kernel/gate.js.map +1 -1
- package/dist/session-ledger/project-ledger.d.ts +17 -0
- package/dist/session-ledger/project-ledger.js +443 -0
- package/dist/session-ledger/project-ledger.js.map +1 -0
- package/dist/stage-evidence/live-writer.d.ts +2 -2
- package/dist/stage-evidence/live-writer.js +11 -1
- package/dist/stage-evidence/live-writer.js.map +1 -1
- package/dist/stage-evidence/marker-parse.d.ts +2 -2
- package/dist/stage-evidence/marker-parse.js +11 -1
- package/dist/stage-evidence/marker-parse.js.map +1 -1
- package/dist/stage-evidence/narration.d.ts +2 -2
- package/dist/stage-evidence/narration.js +11 -1
- package/dist/stage-evidence/narration.js.map +1 -1
- package/dist/{stages-B-5fe_GW.d.ts → stages-DwQ5X3Bd.d.ts} +1 -1
- package/package.json +1 -1
- package/runtime/AGENT-BOOTSTRAP.md +1 -1
- package/runtime/hooks/agent-entry-gate.mjs +1 -1
- package/runtime/hooks/agent-entry-prompt-gate.mjs +1 -1
- package/runtime/hooks/context-refresh-trigger.mjs +13 -2
- package/runtime/hooks/lib/context-seam-emit.mjs +21 -9
- package/runtime/scripts/context-seam.mjs +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# paqad-ai
|
|
2
2
|
|
|
3
|
+
## 1.43.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3bc15df: Publish two measured, reproducible benchmark numbers with methodology and caveats
|
|
8
|
+
(issue #285). Adds read-only repo tooling: `scripts/measure-footprint.mjs` reports the
|
|
9
|
+
resident session-start token footprint per area (real tokenizer via
|
|
10
|
+
`src/context/tokenizer-cache.ts`, labelled char/4 fallback), and
|
|
11
|
+
`scripts/rule-findings-stats.mjs` reads the existing `rule-evidence` ledger via
|
|
12
|
+
`readProjectEvents` and buckets deterministic findings by ISO week. Results, method, run
|
|
13
|
+
counts, tokenizer version, per-tier applicability, and caveats live in
|
|
14
|
+
`docs/instructions/benchmarks/measured.md`. The two unbenchmarked "60-85%" README claims
|
|
15
|
+
are replaced with the measured 49-61% resident-load reduction and a link to the method.
|
|
16
|
+
No product behavior changes; `rag_enabled` stays default off.
|
|
17
|
+
|
|
18
|
+
## 1.42.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- 561665d: Token-neutral by default: lean rule loading is now the default delivery path (issue #284).
|
|
23
|
+
|
|
24
|
+
A new `lean_rules` flag (default **on**, env `PAQAD_LEAN_RULES`) makes the always-resident rule manifest plus trigger-loaded applicable rule text the default, instead of loading the whole `docs/instructions/rules` tree every session. The framework bootstrap and the Claude Code prompt-gate now read `.paqad/context/session-context.md` artifact-first, falling back to the full rule load only when the artifact is missing. On Claude Code the session-time seam and the background refresh trigger are ungated from `rag_enabled` so the rule slice is injected and kept current with no embedding, index, or provider call on the lean path; `rag_enabled` continues to govern only what retrieval/memory/drift sections compose into the same artifact. A committed resident-footprint budget test and a `paqad-ai doctor` readout gate the token cost. `lean_rules=false` restores the previous full-load behaviour exactly, and paqad-disabled stays a pure no-op.
|
|
25
|
+
|
|
3
26
|
## 1.41.1
|
|
4
27
|
|
|
5
28
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -52,16 +52,16 @@ No account, no API key, no subscription. Prefer not to install anything? Run `np
|
|
|
52
52
|
|
|
53
53
|
## What you get, at a glance
|
|
54
54
|
|
|
55
|
-
| Area | What it means for you
|
|
56
|
-
| ---------------------------- |
|
|
57
|
-
| **One setup, every tool** | Configure Claude, Cursor, Copilot, Gemini, and the rest from one source of truth
|
|
58
|
-
| **Workflows, not prompts** | Your team's process runs the same way every time, instead of being re-typed
|
|
59
|
-
| **Proof, not promises** | Automatic checks confirm tests, specs, docs, and security before "done" counts
|
|
60
|
-
| **Security as a workflow** | A full OWASP pentest pass, with retests, built in
|
|
61
|
-
| **Design as a workflow** | Your UI audited against your own design system
|
|
62
|
-
| **Docs that stay current** | The framework keeps your documentation in sync with the code
|
|
63
|
-
| **Fewer tokens, on purpose** | Loads
|
|
64
|
-
| **Runs locally** | Your code stays on your machine, with an audit trail you can keep
|
|
55
|
+
| Area | What it means for you |
|
|
56
|
+
| ---------------------------- | -------------------------------------------------------------------------------------- |
|
|
57
|
+
| **One setup, every tool** | Configure Claude, Cursor, Copilot, Gemini, and the rest from one source of truth |
|
|
58
|
+
| **Workflows, not prompts** | Your team's process runs the same way every time, instead of being re-typed |
|
|
59
|
+
| **Proof, not promises** | Automatic checks confirm tests, specs, docs, and security before "done" counts |
|
|
60
|
+
| **Security as a workflow** | A full OWASP pentest pass, with retests, built in |
|
|
61
|
+
| **Design as a workflow** | Your UI audited against your own design system |
|
|
62
|
+
| **Docs that stay current** | The framework keeps your documentation in sync with the code |
|
|
63
|
+
| **Fewer tokens, on purpose** | Loads a lean resident slice, not the whole repo. Measured 49-61% smaller resident load |
|
|
64
|
+
| **Runs locally** | Your code stays on your machine, with an audit trail you can keep |
|
|
65
65
|
|
|
66
66
|
The rest of this page walks through each of these. The [full docs](https://paqad.ai/docs.html) go deeper on every command and concept.
|
|
67
67
|
|
|
@@ -267,7 +267,13 @@ Documentation is a real output here, not an afterthought you maintain by hand. A
|
|
|
267
267
|
|
|
268
268
|
## The right context, with fewer tokens
|
|
269
269
|
|
|
270
|
-
Your agent does not need your whole repo. It needs the right files. And since every model gets worse on a bloated context, loading less is not just cheaper, it makes the answers better.
|
|
270
|
+
Your agent does not need your whole repo. It needs the right files. And since every model gets worse on a bloated context, loading less is not just cheaper, it makes the answers better.
|
|
271
|
+
|
|
272
|
+
paqad-ai keeps the session-start load lean: a rule manifest plus the files a task actually touches, instead of the whole rule tree. Measured across two projects, that resident load is **49-61% smaller** than loading everything (paqad-ai's own repo: 61%; a fresh React onboard: 49%). Both used the char/4 heuristic tokenizer, so treat them as an honest floor, not a marketing ceiling. The method, the per-project numbers, and the caveats are in [`docs/instructions/benchmarks/measured.md`](docs/instructions/benchmarks/measured.md), and you can reproduce them in your own repo:
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
node scripts/measure-footprint.mjs --project .
|
|
276
|
+
```
|
|
271
277
|
|
|
272
278
|
- It splits files at natural boundaries (functions and classes), not at arbitrary line counts.
|
|
273
279
|
- It ranks each piece by five signals: meaning, keywords, the symbols involved, how close the file is to the task, and how deeply nested it is.
|
package/dist/cli/index.js
CHANGED
|
@@ -665,7 +665,8 @@ function resolveFrameworkConfigFromMap(raw) {
|
|
|
665
665
|
market_research: rb("market_research"),
|
|
666
666
|
design_research: rb("design_research"),
|
|
667
667
|
team_agents: rb("team_agents"),
|
|
668
|
-
analytics_instrumentation: rb("analytics_instrumentation")
|
|
668
|
+
analytics_instrumentation: rb("analytics_instrumentation"),
|
|
669
|
+
lean_rules: rb("lean_rules")
|
|
669
670
|
},
|
|
670
671
|
research: {
|
|
671
672
|
depth: asEnum(
|
|
@@ -1023,6 +1024,7 @@ function frameworkOverridesToFlat(overrides) {
|
|
|
1023
1024
|
f.analytics_instrumentation,
|
|
1024
1025
|
d.features.analytics_instrumentation
|
|
1025
1026
|
);
|
|
1027
|
+
put("lean_rules", f.lean_rules, d.features.lean_rules);
|
|
1026
1028
|
}
|
|
1027
1029
|
if (overrides.research) {
|
|
1028
1030
|
put("research_depth", overrides.research.depth, d.research.depth);
|
|
@@ -1233,6 +1235,15 @@ var init_framework_config = __esm({
|
|
|
1233
1235
|
section: "Feature flags",
|
|
1234
1236
|
comment: "Opt in to complementary analytics instrumentation (issue #241, refined #279). OFF (default) is silent; ON authorizes wiring tracking + a per-event tracking-plan doc."
|
|
1235
1237
|
},
|
|
1238
|
+
{
|
|
1239
|
+
key: "lean_rules",
|
|
1240
|
+
env: "PAQAD_LEAN_RULES",
|
|
1241
|
+
type: "boolean",
|
|
1242
|
+
default: true,
|
|
1243
|
+
group: "app",
|
|
1244
|
+
section: "Feature flags",
|
|
1245
|
+
comment: "Token-neutral rule loading (issue #284). ON (default) delivers the lean rule contract (manifest + only the rule text that applies to the files in play) and lifts the full-load mandate. OFF restores loading docs/instructions/rules in full every session."
|
|
1246
|
+
},
|
|
1236
1247
|
// ── rag group ──────────────────────────────────────────────────────────
|
|
1237
1248
|
{
|
|
1238
1249
|
key: "rag_enabled",
|
|
@@ -1580,7 +1591,8 @@ var init_framework_config = __esm({
|
|
|
1580
1591
|
"market_research",
|
|
1581
1592
|
"design_research",
|
|
1582
1593
|
"team_agents",
|
|
1583
|
-
"analytics_instrumentation"
|
|
1594
|
+
"analytics_instrumentation",
|
|
1595
|
+
"lean_rules"
|
|
1584
1596
|
]
|
|
1585
1597
|
},
|
|
1586
1598
|
{ present: (p) => p.research !== void 0, keys: ["research_depth"] },
|
|
@@ -3464,7 +3476,8 @@ var init_project_profile_schema = __esm({
|
|
|
3464
3476
|
market_research: { type: "boolean" },
|
|
3465
3477
|
design_research: { type: "boolean" },
|
|
3466
3478
|
team_agents: { type: "boolean" },
|
|
3467
|
-
analytics_instrumentation: { type: "boolean" }
|
|
3479
|
+
analytics_instrumentation: { type: "boolean" },
|
|
3480
|
+
lean_rules: { type: "boolean" }
|
|
3468
3481
|
}
|
|
3469
3482
|
},
|
|
3470
3483
|
enterprise: {
|
|
@@ -18266,6 +18279,7 @@ var HealthChecker = class {
|
|
|
18266
18279
|
this.checkMcp(projectRoot, profile),
|
|
18267
18280
|
this.checkSkillCache(projectRoot),
|
|
18268
18281
|
this.checkContextHitRate(projectRoot, profile),
|
|
18282
|
+
this.checkLeanRuleFootprint(projectRoot),
|
|
18269
18283
|
this.checkClassificationOverrideRate(projectRoot),
|
|
18270
18284
|
...await this.checkRag(projectRoot, profile)
|
|
18271
18285
|
];
|
|
@@ -18794,6 +18808,37 @@ var HealthChecker = class {
|
|
|
18794
18808
|
mcp_usage_rate: 0
|
|
18795
18809
|
};
|
|
18796
18810
|
}
|
|
18811
|
+
/**
|
|
18812
|
+
* Issue #284 — the resident rule-footprint readout. Reports how many bytes the lean
|
|
18813
|
+
* session-context artifact carries versus loading the full `docs/instructions/rules`
|
|
18814
|
+
* tree, computed per project (no hard-coded sizes). A present, smaller artifact is a
|
|
18815
|
+
* pass with the savings; an artifact that is not smaller than the full rule set warns
|
|
18816
|
+
* (lean loading is not paying off). A missing artifact is a pass: full-load is the
|
|
18817
|
+
* documented fallback and the artifact regenerates on the next refresh/onboard.
|
|
18818
|
+
*/
|
|
18819
|
+
checkLeanRuleFootprint(projectRoot) {
|
|
18820
|
+
const name = "Lean rule footprint acceptable";
|
|
18821
|
+
const rulesRoot = join58(projectRoot, PATHS.RULES_DIR);
|
|
18822
|
+
if (!existsSync32(rulesRoot)) {
|
|
18823
|
+
return pass(name, "No rules directory to load \u2014 nothing to slim");
|
|
18824
|
+
}
|
|
18825
|
+
const fullRulesBytes = walk2(rulesRoot).filter((file) => file.endsWith(".md")).reduce((sum2, file) => sum2 + statSync4(file).size, 0);
|
|
18826
|
+
const artifactPath = join58(projectRoot, PATHS.CONTEXT_SESSION_ARTIFACT);
|
|
18827
|
+
if (!existsSync32(artifactPath)) {
|
|
18828
|
+
return pass(
|
|
18829
|
+
name,
|
|
18830
|
+
"Lean rule artifact not generated yet \u2014 full rule load is the fallback until the next refresh"
|
|
18831
|
+
);
|
|
18832
|
+
}
|
|
18833
|
+
const residentBytes = statSync4(artifactPath).size;
|
|
18834
|
+
const pct = fullRulesBytes > 0 ? Math.round(residentBytes / fullRulesBytes * 100) : 0;
|
|
18835
|
+
const detail = `Resident rule context is ${residentBytes} bytes vs ${fullRulesBytes} bytes for the full rule set (${pct}% of full)`;
|
|
18836
|
+
return residentBytes < fullRulesBytes || fullRulesBytes === 0 ? pass(name, detail) : warn(
|
|
18837
|
+
name,
|
|
18838
|
+
`${detail} \u2014 lean loading is not reducing the resident footprint`,
|
|
18839
|
+
"Ensure lean_rules is on and re-run `paqad-ai rag refresh-context` to recompose the lean artifact."
|
|
18840
|
+
);
|
|
18841
|
+
}
|
|
18797
18842
|
checkClassificationOverrideRate(projectRoot) {
|
|
18798
18843
|
const path11 = join58(projectRoot, PATHS.AGENCY_CACHE_DIR, "classification-history.json");
|
|
18799
18844
|
if (!existsSync32(path11)) {
|
|
@@ -23982,7 +24027,8 @@ function buildProjectProfile(selections, snapshot, overrides, projectRoot) {
|
|
|
23982
24027
|
market_research: false,
|
|
23983
24028
|
design_research: false,
|
|
23984
24029
|
team_agents: true,
|
|
23985
|
-
analytics_instrumentation: false
|
|
24030
|
+
analytics_instrumentation: false,
|
|
24031
|
+
lean_rules: true
|
|
23986
24032
|
},
|
|
23987
24033
|
// Issue #187 — emit the enterprise block at onboarding so the opt-in
|
|
23988
24034
|
// evidence-ledger / AI-BOM / compliance-citation switches are visible and
|
|
@@ -26076,7 +26122,7 @@ init_cancelled_error();
|
|
|
26076
26122
|
init_events();
|
|
26077
26123
|
|
|
26078
26124
|
// src/index.ts
|
|
26079
|
-
var VERSION = "1.
|
|
26125
|
+
var VERSION = "1.43.0";
|
|
26080
26126
|
|
|
26081
26127
|
// src/cli/commands/audit.ts
|
|
26082
26128
|
init_esm_shims();
|
|
@@ -33845,6 +33891,7 @@ import { readFileSync as readFileSync76 } from "fs";
|
|
|
33845
33891
|
import { isAbsolute as isAbsolute5, join as join174 } from "path";
|
|
33846
33892
|
import { confirm, input as input2, select as select3 } from "@inquirer/prompts";
|
|
33847
33893
|
import { Command as Command18 } from "commander";
|
|
33894
|
+
init_framework_config();
|
|
33848
33895
|
|
|
33849
33896
|
// src/context/codebase-memory.ts
|
|
33850
33897
|
init_esm_shims();
|
|
@@ -34808,6 +34855,17 @@ function createRagCommand() {
|
|
|
34808
34855
|
command.command("refresh-context").description(
|
|
34809
34856
|
"Sync the index, retrieve slices, and recompose session context (background worker)"
|
|
34810
34857
|
).option("--project-root <path>", "Project root", process.cwd()).option("--quiet", "Suppress output (used by the background trigger)").action(async (options) => {
|
|
34858
|
+
const ragEnabled = resolveFrameworkConfig(options.projectRoot).intelligence.rag_enabled;
|
|
34859
|
+
if (!ragEnabled) {
|
|
34860
|
+
const target2 = await refreshRuleContext(options.projectRoot, {});
|
|
34861
|
+
if (!options.quiet) {
|
|
34862
|
+
process.stdout.write(
|
|
34863
|
+
`${target2 ? `wrote ${target2}` : "nothing to compose"}; rule-only (rag off)
|
|
34864
|
+
`
|
|
34865
|
+
);
|
|
34866
|
+
}
|
|
34867
|
+
return;
|
|
34868
|
+
}
|
|
34811
34869
|
const sync = await backgroundIndexSync(options.projectRoot);
|
|
34812
34870
|
const slices = await gatherWorkingSetSlices(options.projectRoot, {
|
|
34813
34871
|
recordEvidence: { adapter: "engine" }
|