@drkmttr/adhere 0.18.0 → 0.21.2
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 +1099 -1066
- package/package.json +15 -15
- package/presets/README.md +132 -0
- package/skills/adhere/SKILL.md +51 -33
- package/skills/adhere-setup/SKILL.md +77 -53
- package/src/cli.ts +133 -14
- package/src/config.ts +157 -138
- package/src/create/agents.ts +149 -0
- package/src/create/ask.ts +147 -0
- package/src/create/look.ts +140 -0
- package/src/create/wizard.ts +432 -0
- package/src/index.ts +2 -0
- package/src/init.ts +24 -4
- package/src/install.ts +30 -24
- package/src/instructions.ts +76 -0
- package/src/markdown.ts +3 -9
- package/src/rules.ts +42 -45
- package/src/services/AdhereConfig.ts +31 -18
- package/src/services/Credentials.ts +14 -8
- package/src/services/Jev.reads.test.ts +26 -2
- package/src/services/Jev.ts +36 -14
- package/src/wording.ts +1 -1
- package/src/workflows/audit.ts +84 -16
- package/src/workflows/format.ts +97 -0
- package/src/workspaces.test.ts +37 -1
- package/src/workspaces.ts +121 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drkmttr/adhere",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Lints a repository against the rules in .adhere/, judged by Jev.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,32 +38,32 @@
|
|
|
38
38
|
"prepare": "vp config"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"effect": "4.0.
|
|
41
|
+
"effect": "4.0.3"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@effect/platform-bun": "4.0.
|
|
44
|
+
"@effect/platform-bun": "4.0.3",
|
|
45
45
|
"@types/bun": "^1.4.2",
|
|
46
|
-
"@types/node": "^
|
|
46
|
+
"@types/node": "^26.0.0",
|
|
47
47
|
"release-it": "^21.1.0",
|
|
48
|
-
"typescript": "7.1.0-dev.
|
|
48
|
+
"typescript": "7.1.0-dev.20261012.1",
|
|
49
49
|
"vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
|
|
50
50
|
"vite-plus": "1.1.0",
|
|
51
|
-
"vitest": "5.0.
|
|
51
|
+
"vitest": "5.0.5"
|
|
52
52
|
},
|
|
53
53
|
"overrides": {
|
|
54
|
-
"@effect/platform-node-shared": "4.0.
|
|
54
|
+
"@effect/platform-node-shared": "4.0.3",
|
|
55
55
|
"vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
|
|
56
|
-
"vitest": "5.0.
|
|
56
|
+
"vitest": "5.0.5"
|
|
57
57
|
},
|
|
58
58
|
"devEngines": {
|
|
59
59
|
"packageManager": {
|
|
60
60
|
"name": "bun",
|
|
61
|
-
"version": "1.4.
|
|
61
|
+
"version": "1.4.3",
|
|
62
62
|
"onFail": "download"
|
|
63
63
|
},
|
|
64
64
|
"runtime": {
|
|
65
65
|
"name": "node",
|
|
66
|
-
"version": "
|
|
66
|
+
"version": "26.11.1",
|
|
67
67
|
"onFail": "download"
|
|
68
68
|
}
|
|
69
69
|
},
|
|
@@ -90,10 +90,10 @@
|
|
|
90
90
|
"--force"
|
|
91
91
|
],
|
|
92
92
|
"optionalDependencies": {
|
|
93
|
-
"@drkmttr/adhere-darwin-arm64": "0.
|
|
94
|
-
"@drkmttr/adhere-darwin-x64": "0.
|
|
95
|
-
"@drkmttr/adhere-linux-arm64": "0.
|
|
96
|
-
"@drkmttr/adhere-linux-x64": "0.
|
|
97
|
-
"@drkmttr/adhere-win32-x64": "0.
|
|
93
|
+
"@drkmttr/adhere-darwin-arm64": "0.21.2",
|
|
94
|
+
"@drkmttr/adhere-darwin-x64": "0.21.2",
|
|
95
|
+
"@drkmttr/adhere-linux-arm64": "0.21.2",
|
|
96
|
+
"@drkmttr/adhere-linux-x64": "0.21.2",
|
|
97
|
+
"@drkmttr/adhere-win32-x64": "0.21.2"
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Presets
|
|
2
|
+
|
|
3
|
+
Every rule in adhere's built-in presets is listed below, with a one-line
|
|
4
|
+
summary. Each id links to the full rule, and is the id that reports,
|
|
5
|
+
`overrides`, and `adhere-ignore` comments use. [Presets](../README.md#presets)
|
|
6
|
+
says how to name a preset or one of its topics.
|
|
7
|
+
|
|
8
|
+
## typescript
|
|
9
|
+
|
|
10
|
+
- **Source.** The TypeScript Handbook and the Google TypeScript Style Guide.
|
|
11
|
+
- **Checked by a linter instead.** The preset has no rules for these, since
|
|
12
|
+
typescript-eslint and ESLint check them exactly: unhandled promises
|
|
13
|
+
(`no-floating-promises`), throwing non-errors (`only-throw-error`), `any`
|
|
14
|
+
(`no-explicit-any`), exhaustive switches (`switch-exhaustiveness-check`), a
|
|
15
|
+
lost `cause` (`preserve-caught-error`), and empty catch blocks (`no-empty`).
|
|
16
|
+
|
|
17
|
+
- [`typescript/async/concurrent-independent-work`](./typescript/async/concurrent-independent-work/RULE.md): Independent awaited calls run concurrently, not one after another.
|
|
18
|
+
- [`typescript/async/network-calls-have-timeouts`](./typescript/async/network-calls-have-timeouts/RULE.md): HTTP requests carry a timeout or an abort signal.
|
|
19
|
+
- [`typescript/design/no-argument-mutation`](./typescript/design/no-argument-mutation/RULE.md): Functions return changed copies instead of mutating arguments.
|
|
20
|
+
- [`typescript/errors/no-swallowed-errors`](./typescript/errors/no-swallowed-errors/RULE.md): Caught errors are handled, rethrown, or returned as failures.
|
|
21
|
+
- [`typescript/errors/release-on-every-path`](./typescript/errors/release-on-every-path/RULE.md): Acquired resources are released on every path, including errors.
|
|
22
|
+
- [`typescript/testing/assert-outcomes`](./typescript/testing/assert-outcomes/RULE.md): Tests assert results and effects, not only that code ran.
|
|
23
|
+
- [`typescript/testing/independent-tests`](./typescript/testing/independent-tests/RULE.md): Each test sets up its own state and relies on no other test.
|
|
24
|
+
- [`typescript/types/assertions-only-when-proven`](./typescript/types/assertions-only-when-proven/RULE.md): Type assertions claim only what surrounding code has proven.
|
|
25
|
+
- [`typescript/types/derive-dont-restate`](./typescript/types/derive-dont-restate/RULE.md): Types are derived from their source instead of restated by hand.
|
|
26
|
+
- [`typescript/types/unrepresentable-invalid-states`](./typescript/types/unrepresentable-invalid-states/RULE.md): Types make invalid field combinations unrepresentable.
|
|
27
|
+
- [`typescript/types/validate-external-data`](./typescript/types/validate-external-data/RULE.md): Data from outside is checked at runtime before use.
|
|
28
|
+
|
|
29
|
+
## react
|
|
30
|
+
|
|
31
|
+
- **Source.** react.dev, mostly
|
|
32
|
+
[You Might Not Need an Effect](https://react.dev/learn/you-might-not-need-an-effect)
|
|
33
|
+
and
|
|
34
|
+
[Choosing the State Structure](https://react.dev/learn/choosing-the-state-structure).
|
|
35
|
+
- **Checked by a linter instead.** The preset has no rules for these, since
|
|
36
|
+
the React Compiler's lint rules check them, in
|
|
37
|
+
[eslint-plugin-react-hooks](https://react.dev/reference/eslint-plugin-react-hooks)'s
|
|
38
|
+
recommended set and in Oxlint: pure render (`purity`), props and state
|
|
39
|
+
never mutated (`immutability`), refs not read during render (`refs`), no
|
|
40
|
+
`setState` in render or synchronously in an effect (`set-state-in-render`,
|
|
41
|
+
`set-state-in-effect`), which covers state derived in an effect, and no
|
|
42
|
+
component defined inside another (`static-components`).
|
|
43
|
+
|
|
44
|
+
- [`react/effects/clean-up-what-they-start`](./react/effects/clean-up-what-they-start/RULE.md): Effects return cleanup that undoes what they started.
|
|
45
|
+
- [`react/effects/event-logic-in-handlers`](./react/effects/event-logic-in-handlers/RULE.md): Code responding to a user action runs in its event handler.
|
|
46
|
+
- [`react/effects/external-stores-use-sync-external-store`](./react/effects/external-stores-use-sync-external-store/RULE.md): External stores are read with `useSyncExternalStore`.
|
|
47
|
+
- [`react/effects/fetches-ignore-stale-responses`](./react/effects/fetches-ignore-stale-responses/RULE.md): Effects that fetch ignore or abort stale responses.
|
|
48
|
+
- [`react/effects/notify-parents-in-handlers`](./react/effects/notify-parents-in-handlers/RULE.md): Parents are notified in the handler that makes the change.
|
|
49
|
+
- [`react/server/no-private-data-to-client`](./react/server/no-private-data-to-client/RULE.md): Client Components receive only the fields they show.
|
|
50
|
+
- [`react/server/server-functions-authorize-and-validate`](./react/server/server-functions-authorize-and-validate/RULE.md): Server Functions authorize callers and validate arguments.
|
|
51
|
+
- [`react/state/no-contradictory-state`](./react/state/no-contradictory-state/RULE.md): One status value replaces booleans that can contradict.
|
|
52
|
+
- [`react/state/no-props-copied-into-state`](./react/state/no-props-copied-into-state/RULE.md): Props are read during render, not copied into state.
|
|
53
|
+
- [`react/state/store-ids-not-copies`](./react/state/store-ids-not-copies/RULE.md): State holds a selected item's id, not a copy of the item.
|
|
54
|
+
|
|
55
|
+
## security
|
|
56
|
+
|
|
57
|
+
- **Source.** OWASP's cheat sheets.
|
|
58
|
+
|
|
59
|
+
- [`security/constant-time-secret-compare`](./security/constant-time-secret-compare/RULE.md): Received secrets are compared in constant time.
|
|
60
|
+
- [`security/no-secrets-in-output`](./security/no-secrets-in-output/RULE.md): Secrets stay out of logs, errors, and HTTP responses.
|
|
61
|
+
- [`security/no-untrusted-input-in-commands-or-paths`](./security/no-untrusted-input-in-commands-or-paths/RULE.md): Untrusted input stays out of command strings and unchecked paths.
|
|
62
|
+
- [`security/parameterized-queries`](./security/parameterized-queries/RULE.md): SQL values from outside are passed as bound parameters.
|
|
63
|
+
|
|
64
|
+
## effect
|
|
65
|
+
|
|
66
|
+
- **Source.** The
|
|
67
|
+
[effect-solutions](https://github.com/kitlangton/effect-solutions) docs and
|
|
68
|
+
the [effect/platform](https://effect.website/docs/platform/introduction/)
|
|
69
|
+
docs.
|
|
70
|
+
|
|
71
|
+
- [`effect/basics/gen-for-sequencing`](./effect/basics/gen-for-sequencing/RULE.md): Sequential effectful steps use `Effect.gen` and `yield*`.
|
|
72
|
+
- [`effect/basics/instrument-with-pipe`](./effect/basics/instrument-with-pipe/RULE.md): Timeouts, retries, logging, and spans attach with `.pipe`.
|
|
73
|
+
- [`effect/config/business-logic-depends-on-config-service`](./effect/config/business-logic-depends-on-config-service/RULE.md): Business logic depends on a config service, not Config reads.
|
|
74
|
+
- [`effect/config/secrets-are-redacted`](./effect/config/secrets-are-redacted/RULE.md): Tokens, passwords, and keys are read with `Config.Redacted`.
|
|
75
|
+
- [`effect/config/tests-provide-values-directly`](./effect/config/tests-provide-values-directly/RULE.md): Tests supply config with `Layer.succeed` on the config service.
|
|
76
|
+
- [`effect/config/validate-with-schema`](./effect/config/validate-with-schema/RULE.md): Constrained config values are validated as they are read.
|
|
77
|
+
- [`effect/data/brand-meaningful-primitives`](./effect/data/brand-meaningful-primitives/RULE.md): Meaningful primitives in domain types are branded schemas.
|
|
78
|
+
- [`effect/data/variants-are-tagged-unions`](./effect/data/variants-are-tagged-unions/RULE.md): Domain variants are tagged schemas in a union.
|
|
79
|
+
- [`effect/errors/catch-defects-at-boundaries-only`](./effect/errors/catch-defects-at-boundaries-only/RULE.md): Defects are caught only at system boundaries.
|
|
80
|
+
- [`effect/errors/defects-for-bugs`](./effect/errors/defects-for-bugs/RULE.md): Bugs and invariant violations are defects, not typed errors.
|
|
81
|
+
- [`effect/errors/wrap-external-errors`](./effect/errors/wrap-external-errors/RULE.md): External errors are wrapped in tagged errors.
|
|
82
|
+
- [`effect/services/dependencies-through-layers`](./effect/services/dependencies-through-layers/RULE.md): Service dependencies are yielded inside the service's Layer.
|
|
83
|
+
- [`effect/services/fresh-layer-per-test`](./effect/services/fresh-layer-per-test/RULE.md): Each `it.effect` test provides its own layer.
|
|
84
|
+
- [`effect/services/memoize-parameterized-layers`](./effect/services/memoize-parameterized-layers/RULE.md): Parameterized layers are built once and stored in a constant.
|
|
85
|
+
- [`effect/services/no-mutable-state`](./effect/services/no-mutable-state/RULE.md): Service interfaces expose only readonly members.
|
|
86
|
+
- [`effect/testing/test-clock-for-time`](./effect/testing/test-clock-for-time/RULE.md): Tests that depend on time use `TestClock`.
|
|
87
|
+
|
|
88
|
+
## alchemy
|
|
89
|
+
|
|
90
|
+
- **Source.** alchemy's docs and blog.
|
|
91
|
+
|
|
92
|
+
- [`alchemy/apis/match-remote-errors-by-tag`](./alchemy/apis/match-remote-errors-by-tag/RULE.md): Remote errors are matched by tag and data, not `instanceof`.
|
|
93
|
+
- [`alchemy/apis/schemas-at-trust-boundaries`](./alchemy/apis/schemas-at-trust-boundaries/RULE.md): Outside input is schema-validated at trust boundaries.
|
|
94
|
+
- [`alchemy/data/commit-migrations-then-deploy`](./alchemy/data/commit-migrations-then-deploy/RULE.md): Migrations are committed ahead of time and applied as committed.
|
|
95
|
+
- [`alchemy/data/hyperdrive-direct-origin`](./alchemy/data/hyperdrive-direct-origin/RULE.md): Hyperdrive points at the database's direct endpoint.
|
|
96
|
+
- [`alchemy/data/migrations-use-direct-url`](./alchemy/data/migrations-use-direct-url/RULE.md): Migration runners connect with the database's direct URL.
|
|
97
|
+
- [`alchemy/data/never-disable-tls-verification`](./alchemy/data/never-disable-tls-verification/RULE.md): Database connections verify the server's TLS certificate.
|
|
98
|
+
- [`alchemy/data/private-endpoint-at-runtime`](./alchemy/data/private-endpoint-at-runtime/RULE.md): Service code reaches its database through the private binding.
|
|
99
|
+
- [`alchemy/data/single-migration-owner`](./alchemy/data/single-migration-owner/RULE.md): Each database has exactly one migration owner.
|
|
100
|
+
- [`alchemy/durable/idempotent-event-handlers`](./alchemy/durable/idempotent-event-handlers/RULE.md): Handlers for at-least-once events are idempotent.
|
|
101
|
+
- [`alchemy/durable/io-inside-steps`](./alchemy/durable/io-inside-steps/RULE.md): Workflow I/O runs inside steps; replayed code stays deterministic.
|
|
102
|
+
- [`alchemy/durable/no-self-triggering-bucket-writes`](./alchemy/durable/no-self-triggering-bucket-writes/RULE.md): Bucket handlers filter out events from their own writes.
|
|
103
|
+
- [`alchemy/durable/stable-step-names`](./alchemy/durable/stable-step-names/RULE.md): Workflow step names stay stable across replays.
|
|
104
|
+
- [`alchemy/durable/webhook-state-is-truth`](./alchemy/durable/webhook-state-is-truth/RULE.md): Paid access depends on webhook-recorded state, not success URLs.
|
|
105
|
+
- [`alchemy/providers/diff-guards-unresolved-props`](./alchemy/providers/diff-guards-unresolved-props/RULE.md): Provider diffs guard unresolved props with `isResolved`.
|
|
106
|
+
- [`alchemy/providers/idempotent-delete`](./alchemy/providers/idempotent-delete/RULE.md): Provider delete treats an already-gone resource as success.
|
|
107
|
+
- [`alchemy/providers/lazy-layer-construction`](./alchemy/providers/lazy-layer-construction/RULE.md): Provider layers defer credentials and connections until use.
|
|
108
|
+
- [`alchemy/providers/reconcile-from-observed-state`](./alchemy/providers/reconcile-from-observed-state/RULE.md): Provider reconcile converges from the resource's live state.
|
|
109
|
+
- [`alchemy/resources/anchor-paths-with-import-meta`](./alchemy/resources/anchor-paths-with-import-meta/RULE.md): Path props of resources declared outside the run directory use `import.meta`.
|
|
110
|
+
- [`alchemy/resources/idempotent-actions-and-seeds`](./alchemy/resources/idempotent-actions-and-seeds/RULE.md): Actions and seed files are safe to run again.
|
|
111
|
+
- [`alchemy/resources/previews-reference-shared-resources`](./alchemy/resources/previews-reference-shared-resources/RULE.md): Preview stages reference shared resources and add cheap pieces.
|
|
112
|
+
- [`alchemy/resources/protect-irreplaceable-data`](./alchemy/resources/protect-irreplaceable-data/RULE.md): Buckets and databases with irreplaceable data are retained.
|
|
113
|
+
- [`alchemy/resources/remote-state-for-ci`](./alchemy/resources/remote-state-for-ci/RULE.md): CI and multi-machine stacks use a shared state store.
|
|
114
|
+
- [`alchemy/resources/stable-logical-ids`](./alchemy/resources/stable-logical-ids/RULE.md): Resource logical ids stay the same across deploys.
|
|
115
|
+
- [`alchemy/resources/stage-unique-physical-names`](./alchemy/resources/stage-unique-physical-names/RULE.md): Global physical names are derived per stage.
|
|
116
|
+
- [`alchemy/runtime/bind-tag-not-implementation`](./alchemy/runtime/bind-tag-not-implementation/RULE.md): Other runtimes bind the Tag; only the Stack provides the Layer.
|
|
117
|
+
- [`alchemy/runtime/deterministic-config-defaults`](./alchemy/runtime/deterministic-config-defaults/RULE.md): Config defaults and fallbacks are deterministic.
|
|
118
|
+
- [`alchemy/runtime/disposables-in-request-scope`](./alchemy/runtime/disposables-in-request-scope/RULE.md): Disposables are acquired inside handlers, within request scope.
|
|
119
|
+
- [`alchemy/runtime/lambda-no-post-response-work`](./alchemy/runtime/lambda-no-post-response-work/RULE.md): Lambda handlers write durable work before responding.
|
|
120
|
+
- [`alchemy/runtime/no-per-request-work-at-construction`](./alchemy/runtime/no-per-request-work-at-construction/RULE.md): Construction builds resources and handlers, not per-request work.
|
|
121
|
+
- [`alchemy/runtime/resolve-config-and-bindings-at-construction`](./alchemy/runtime/resolve-config-and-bindings-at-construction/RULE.md): Config and bindings are resolved at construction, not in handlers.
|
|
122
|
+
- [`alchemy/secrets/let-alchemy-mint-infra-secrets`](./alchemy/secrets/let-alchemy-mint-infra-secrets/RULE.md): Infrastructure tokens are minted once by alchemy, not hardcoded.
|
|
123
|
+
- [`alchemy/secrets/none-in-browser-env`](./alchemy/secrets/none-in-browser-env/RULE.md): Browser-inlined env values hold only public configuration.
|
|
124
|
+
- [`alchemy/secrets/redacted-until-use`](./alchemy/secrets/redacted-until-use/RULE.md): Secrets stay `Redacted` until the call that needs the raw string.
|
|
125
|
+
- [`alchemy/secrets/unwrap-before-compare-or-send`](./alchemy/secrets/unwrap-before-compare-or-send/RULE.md): `Redacted` values are unwrapped before compare, send, or serialize.
|
|
126
|
+
- [`alchemy/security/authorize-public-endpoints`](./alchemy/security/authorize-public-endpoints/RULE.md): Public handlers authenticate and authorize every caller.
|
|
127
|
+
- [`alchemy/security/github-secret-not-variable`](./alchemy/security/github-secret-not-variable/RULE.md): Sensitive CI values use `GitHub.Secret`, not `GitHub.Variable`.
|
|
128
|
+
- [`alchemy/security/identity-from-verified-session`](./alchemy/security/identity-from-verified-session/RULE.md): The acting user comes from the verified session or token.
|
|
129
|
+
- [`alchemy/security/keep-auth-protections-on`](./alchemy/security/keep-auth-protections-on/RULE.md): Auth checks and protections stay enabled.
|
|
130
|
+
- [`alchemy/security/least-privilege-bindings`](./alchemy/security/least-privilege-bindings/RULE.md): Runtimes bind the narrowest capability their calls need.
|
|
131
|
+
- [`alchemy/security/least-privilege-ci-credentials`](./alchemy/security/least-privilege-ci-credentials/RULE.md): CI credentials are scoped to what the stack deploys.
|
|
132
|
+
- [`alchemy/security/lookup-failure-is-not-anonymous`](./alchemy/security/lookup-failure-is-not-anonymous/RULE.md): A failed session lookup is an error, not an anonymous user.
|
package/skills/adhere/SKILL.md
CHANGED
|
@@ -23,10 +23,12 @@ adhere init [--force] # .adhere/config.ts, two example rules, and the
|
|
|
23
23
|
adhere init --shared org/repo # a repo of rules other repos install, with CI and an alchemy stack
|
|
24
24
|
adhere login # save a TypeSafe AI API key; TYPESAFE_API_KEY takes precedence
|
|
25
25
|
adhere validate # rule wording, rules a linter could check, contradictions
|
|
26
|
+
adhere rules create [idea] # wizard: claude, codex, or omp drafts a RULE.md or RULE.ts from excerpts you judge; org rules pushed for a PR
|
|
26
27
|
adhere lint # judge the working directory; exit 1 on an error finding
|
|
27
28
|
adhere lint --limit 0 # compiler-free counts/cache plan; no budgeting
|
|
28
29
|
adhere lint --limit 100 # first 100 files needing requests; all pending rules per file
|
|
29
30
|
adhere lint --yes # send without asking, as in CI
|
|
31
|
+
adhere lint --type-aware # opt in to both compiler symbols and declaration references
|
|
30
32
|
adhere lint --preset effect # add a built-in rule set; the config becomes optional
|
|
31
33
|
adhere lint --filter 'src/**' # read only matching files; repeat, and ! to leave out
|
|
32
34
|
adhere lint --threshold 0.9 # report at another threshold from the cache; judges nothing again
|
|
@@ -38,8 +40,9 @@ adhere skill [docs|setup|fix] # print a skill
|
|
|
38
40
|
|
|
39
41
|
`adhere <command> --help` lists every flag. Version, help, skills, `validate`,
|
|
40
42
|
and planning with `--limit 0` do not start the native compiler. Default `lint`
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
is compiler-free. With `typeAware: true` or `--type-aware`, it starts the compiler
|
|
44
|
+
only during execution, after confirmation, for pending judgments or cached
|
|
45
|
+
findings still needing location.
|
|
43
46
|
|
|
44
47
|
`--limit` now counts files, not rule checks; use the same flag without an extra
|
|
45
48
|
unit selector. Each request-bearing file consumes one slot for all its pending
|
|
@@ -127,7 +130,7 @@ rule takes:
|
|
|
127
130
|
`description`, `must`, `never`, and the rest. Its `appendState(state, file, Bun)`
|
|
128
131
|
runs right before each request for the rule, and what it returns is spread
|
|
129
132
|
over the request's state: `code`, the file's sections as Jev reads them,
|
|
130
|
-
plus the shared context
|
|
133
|
+
plus the shared context enabled by the config's `reads` and `typeAware`. Use it to give Jev what the file cannot show, such
|
|
131
134
|
as a schema another file holds, and name the key it adds in the description.
|
|
132
135
|
Nothing it returns is checked, so it can break its own rule. The rule gets
|
|
133
136
|
requests of its own, repeating the shared context. Hook-owned external data
|
|
@@ -153,7 +156,8 @@ export default defineConfig({
|
|
|
153
156
|
presets: ["typescript", "security"], // built-in rule sets, or topics such as "effect/basics"
|
|
154
157
|
threshold: 0.8, // default 0.8
|
|
155
158
|
sufficiencyThreshold: 0.6, // below it, a finding warns the file and shared context may not show enough
|
|
156
|
-
reads: ["workspacePackages"
|
|
159
|
+
reads: ["workspacePackages"], // default; [] omits workspace context
|
|
160
|
+
typeAware: false, // default; true or --type-aware enables both symbols and references
|
|
157
161
|
exclude: ["**/generated/**"], // files no rule judges
|
|
158
162
|
includeComments: false, // true only for rules about comments
|
|
159
163
|
overrides: {
|
|
@@ -163,14 +167,16 @@ export default defineConfig({
|
|
|
163
167
|
});
|
|
164
168
|
```
|
|
165
169
|
|
|
166
|
-
Top-level `reads`
|
|
167
|
-
rules, including presets.
|
|
168
|
-
`[
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
do not
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
Top-level `reads` chooses workspace context for every audited file and all its
|
|
171
|
+
rules, including presets. It defaults to `["workspacePackages"]`, even without
|
|
172
|
+
a config file; `reads: []` omits that map. `typeAware` defaults to `false`.
|
|
173
|
+
Opting in with `typeAware: true` or `--type-aware` enables both `symbols` and
|
|
174
|
+
`references`, regardless of `reads`. Legacy native-reader entries in `reads`
|
|
175
|
+
alone do not enable the compiler; leaving them out does not disable it when
|
|
176
|
+
type awareness is on. Code alone requires `reads: []` and type awareness off.
|
|
177
|
+
Presets do not own or override this selection. A rule-level `reads`, in
|
|
178
|
+
Markdown front matter, `defineRule`, or an inline rule, has no effect. The
|
|
179
|
+
context maps are:
|
|
174
180
|
|
|
175
181
|
- `workspacePackages`: only packages matched by this file's literal imports,
|
|
176
182
|
as `{ canonicalPackageName: directory }`. Subpaths match the owning package;
|
|
@@ -184,10 +190,14 @@ the config. The available names are:
|
|
|
184
190
|
and narrowing types stay distinct; docs/tags appear once per canonical symbol
|
|
185
191
|
per file. This is not literal IDE hover text: there are no IDE labels or
|
|
186
192
|
selected-call overload presentation. Unused local declarations may have type
|
|
187
|
-
blocks too.
|
|
188
|
-
|
|
189
|
-
-
|
|
190
|
-
|
|
193
|
+
blocks too. Standard-library and Node/Bun built-ins and their methods are
|
|
194
|
+
omitted; project and third-party symbols remain, including built-in-name
|
|
195
|
+
shadows. Built-in type names can still appear inside meaningful signatures.
|
|
196
|
+
- `references`: a flat `Record<string, string>`, as
|
|
197
|
+
`{ "Name:path/to/file.ts": "declarationSnippet" }`, for declarations of symbols
|
|
198
|
+
used by the target code, not incoming call sites. Keys retain names as used,
|
|
199
|
+
including import aliases, and repository-relative pathname casing; alias targets
|
|
200
|
+
are resolved canonically. Each snippet is the smallest
|
|
191
201
|
complete AST declaration scope, with no extra surrounding lines: full function
|
|
192
202
|
bodies; whole arrow/object initializer variable statements, including
|
|
193
203
|
`export const` and semicolons; whole methods/getters/setters, not their classes;
|
|
@@ -201,8 +211,10 @@ the config. The available names are:
|
|
|
201
211
|
exclusions remain. There are no counts, incoming callers, structured locations,
|
|
202
212
|
unresolved lists, full-file collection, or completeness metadata.
|
|
203
213
|
|
|
204
|
-
|
|
205
|
-
native TypeScript compiler through the npm/Bun
|
|
214
|
+
When type awareness is enabled, npm-installed lint uses both `symbols` and
|
|
215
|
+
`references` with adhere's pinned native TypeScript compiler through the npm/Bun
|
|
216
|
+
launcher. Enabled context maps include a self-describing `__comment` in Jev's
|
|
217
|
+
state; top-level guidance identifies only `code` as the audit target. No root `tsconfig.json`
|
|
206
218
|
or root file-list membership is required. During execution, native TypeScript
|
|
207
219
|
opens files with pending judgments or cached findings needing location and
|
|
208
220
|
discovers each file's configured project, including package
|
|
@@ -243,27 +255,32 @@ program graphs can still consume substantial time/memory. Bounding active
|
|
|
243
255
|
documents/snapshots does not make total memory or model payload size constant,
|
|
244
256
|
and oversized contexts are still possible. Context is queried just
|
|
245
257
|
before judge/locate and reused locally. Planning never calls `SourceReads`.
|
|
246
|
-
|
|
247
|
-
binaries
|
|
248
|
-
|
|
249
|
-
|
|
258
|
+
Type-aware source checkouts use their development compiler dependency. Raw
|
|
259
|
+
GitHub binaries have no compiler resources, but run the default compiler-free
|
|
260
|
+
audit with workspace context without special configuration. Use `reads: []`
|
|
261
|
+
for code alone, with type awareness off; use the package launcher or a checkout
|
|
262
|
+
for type-aware execution. Plan-only `--limit 0` needs no compiler or API key.
|
|
250
263
|
|
|
251
264
|
Rules without `appendState` share requests and pay for shared input context
|
|
252
265
|
once per request, not once per rule. Context repeats on request splitting,
|
|
253
266
|
locating findings, and hook requests. Compiler documentation and complete declaration
|
|
254
|
-
scopes add
|
|
267
|
+
scopes add token/privacy cost only when type awareness is enabled, including
|
|
268
|
+
source from files not judged.
|
|
255
269
|
Complete scopes may contain substantially more source/tokens than fixed-line
|
|
256
270
|
excerpts; function bodies are not peeked or capped to seven lines.
|
|
257
271
|
Compiler-provided docs and JSDoc tags can remain present with ordinary comments
|
|
258
|
-
stripped.
|
|
259
|
-
|
|
272
|
+
stripped. Keep `typeAware` off to omit both native maps; `reads` controls only
|
|
273
|
+
workspace context. Use `reads: []` with type awareness off for code alone.
|
|
260
274
|
Plan token/cost estimates include code and cheap workspace metadata only, not
|
|
261
275
|
native context or hook-added data. Actual cost and request splits may therefore
|
|
262
276
|
be higher. Shared state plus any one question must fit 32k tokens, and state
|
|
263
277
|
plus all questions in a request must fit 64k, with 1k reserved for overhead.
|
|
264
|
-
Execution splits question batches
|
|
265
|
-
|
|
266
|
-
`
|
|
278
|
+
Execution splits question batches and checks full budgets before HTTP. On
|
|
279
|
+
context overflow, it retries once without `references` when that map is present,
|
|
280
|
+
keeping target code and `symbols` intact; a further overflow skips the file.
|
|
281
|
+
Complete declaration scopes are not shortened to fit. Symbol strings have
|
|
282
|
+
configurable `maxSymbolLength` and `maxSymbolDocumentationLength` limits, both
|
|
283
|
+
256 by default. Only `appendState` forces a private rule request group.
|
|
267
284
|
|
|
268
285
|
`overrides` changes any rule by the id the report shows, a preset's with the
|
|
269
286
|
preset first, without copying it; an id no rule has refuses the run. `rules`
|
|
@@ -330,8 +347,8 @@ re-judges that rule; a threshold change re-judges nothing.
|
|
|
330
347
|
|
|
331
348
|
Dependencies, related source, reader selection, shared read-context contents,
|
|
332
349
|
and hook-owned external data are deliberately not fingerprinted. If `A.ts` imports
|
|
333
|
-
`B.ts`, changing `B.ts` does not invalidate `A.ts`. Changing config `reads`
|
|
334
|
-
not refresh its cached answers either. This keeps planning cheap but accepts
|
|
350
|
+
`B.ts`, changing `B.ts` does not invalidate `A.ts`. Changing config `reads` or
|
|
351
|
+
`typeAware` does not refresh its cached answers either. This keeps planning cheap but accepts
|
|
335
352
|
stale dependency/context judgments.
|
|
336
353
|
|
|
337
354
|
`planAudit` reads/counts/hashes code, checks the cache, and makes code plus cheap
|
|
@@ -344,8 +361,8 @@ budgeting, native reads, and HTTP execution.
|
|
|
344
361
|
Source reload/hash work is bounded to 8 files; plans retain compact metadata and
|
|
345
362
|
estimates, not all file contents. Only sampled-linter files need a planning
|
|
346
363
|
reread. After confirmation, execution reloads request-bearing files and cached
|
|
347
|
-
finding excerpts, preparing
|
|
348
|
-
cached-unlocated files just before judge/locate. Every reload validates normalized
|
|
364
|
+
finding excerpts, preparing native context only when type awareness is enabled,
|
|
365
|
+
for pending or cached-unlocated files just before judge/locate. Every reload validates normalized
|
|
349
366
|
code and ignore directives against the active plan; changes refuse with rerun
|
|
350
367
|
guidance, without adding persistent-cache keys. A fully cached and located run
|
|
351
368
|
starts no compiler and needs no API key or Jev requests.
|
|
@@ -390,7 +407,8 @@ the file breaks the rule. On a terminal it is amber near its rule's
|
|
|
390
407
|
threshold, within a quarter of the room above it (0.80 to 0.84 at a threshold
|
|
391
408
|
of 0.80), and green above that: a rule whose findings are mostly amber turns
|
|
392
409
|
on where its threshold sits. `context` is its probability that the file and
|
|
393
|
-
shared context show enough to decide
|
|
410
|
+
shared context show enough to decide. Default context is `workspacePackages`;
|
|
411
|
+
`symbols` and `references` require `typeAware: true` or `--type-aware`.
|
|
394
412
|
It is colored the same way around the sufficiency threshold, 0.6
|
|
395
413
|
by default: amber from 0.50 to 0.69, red below. Below 0.6 the finding also
|
|
396
414
|
carries `warning: this file may not show enough to check this rule`. It turns
|
|
@@ -25,10 +25,10 @@ the `packageManager` field in `package.json` names it; with neither, **Ask**.
|
|
|
25
25
|
|
|
26
26
|
| Manager | Add adhere | Run adhere |
|
|
27
27
|
| ------- | -------------------------------- | ------------------ |
|
|
28
|
-
| bun | `bun add -D @drkmttr/adhere` | `
|
|
28
|
+
| bun | `bun add -D @drkmttr/adhere` | `bun run adhere` |
|
|
29
29
|
| pnpm | `pnpm add -D @drkmttr/adhere` | `pnpm exec adhere` |
|
|
30
30
|
| yarn | `yarn add -D @drkmttr/adhere` | `yarn adhere` |
|
|
31
|
-
| npm | `npm install -D @drkmttr/adhere` | `
|
|
31
|
+
| npm | `npm install -D @drkmttr/adhere` | `npm exec adhere` |
|
|
32
32
|
|
|
33
33
|
In a repo with a `package.json`, add adhere as a dev dependency with its
|
|
34
34
|
manager, so the repo pins the version the team and CI run. From then on,
|
|
@@ -37,30 +37,38 @@ wherever this skill says `adhere`, run it the manager's way, as in
|
|
|
37
37
|
|
|
38
38
|
With pnpm, at a workspace root, add `--ignore-workspace-root-check`.
|
|
39
39
|
|
|
40
|
-
Default lint
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
Default lint reads code and `workspacePackages` without starting a compiler.
|
|
41
|
+
`typeAware` defaults to `false`; `typeAware: true` or `--type-aware` opts into
|
|
42
|
+
both `symbols` and `references`, regardless of `reads`. `reads` now controls
|
|
43
|
+
workspace context only, defaulting to `["workspacePackages"]`; legacy native
|
|
44
|
+
reader entries alone do not opt in. Code alone uses `reads: []` with type
|
|
45
|
+
awareness off. Explain the extra context/cost and **Ask** before opting in.
|
|
46
|
+
|
|
47
|
+
With type awareness enabled, native TypeScript starts only during execution,
|
|
48
|
+
after confirmation, when pending judgments or cached findings needing location
|
|
49
|
+
require context. It discovers each file's configured project, including package
|
|
50
|
+
projects under solution roots, and falls back to inferred context for
|
|
51
|
+
unconfigured or excluded files. No root `tsconfig.json` or literal root file-list
|
|
52
|
+
membership is required; do not block setup on either. `.adhere/tsconfig.json`
|
|
53
|
+
only types the config and rules. Planning, `--limit 0`, version, help, skills,
|
|
54
|
+
and validate do not start the compiler.
|
|
49
55
|
|
|
50
56
|
In a repo without a `package.json`, inspect any `adhere` on PATH with
|
|
51
57
|
`adhere --version`, then **Ask** whether to use the npm/Bun package launcher
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
or a raw executable for the same default compiler-free audit. The raw release
|
|
59
|
+
needs no Node or package manager and runs with workspace context without
|
|
60
|
+
special configuration. It cannot run a type-aware audit: use the package
|
|
61
|
+
launcher or a checkout if the user opts in. Do not silently turn off an
|
|
62
|
+
explicitly chosen `typeAware` setting. Only fetch the raw release after the
|
|
63
|
+
user chooses that alternative. On macOS and Linux:
|
|
57
64
|
|
|
58
65
|
```sh
|
|
59
|
-
curl -fsSL
|
|
60
|
-
https://github.com/darkmatter/adhere/releases/latest/download/adhere-$(uname -s)-$(uname -m)
|
|
61
|
-
chmod +x ~/.local/bin/adhere
|
|
66
|
+
curl -fsSL https://github.com/darkmatter/adhere/raw/main/scripts/install.sh | sh
|
|
62
67
|
```
|
|
63
68
|
|
|
69
|
+
On Windows, download `adhere-Windows-x86_64.exe` from
|
|
70
|
+
https://github.com/darkmatter/adhere/releases/latest.
|
|
71
|
+
|
|
64
72
|
Validate and lint's paid requests need a TypeSafe AI API key: `TYPESAFE_API_KEY`,
|
|
65
73
|
or one saved by `adhere login`, which the user runs; never ask for the key in
|
|
66
74
|
chat or print it. Compiler-free planning with `--limit 0` needs no key.
|
|
@@ -139,10 +147,11 @@ the wording of any. Revise drafts the user wants changed and show them again.
|
|
|
139
147
|
- Copy each chosen draft to `.adhere/rules/<topic>/<slug>/RULE.md`.
|
|
140
148
|
- Add chosen presets, or topics, to `presets` in `.adhere/config.ts`. Presets
|
|
141
149
|
use the audit-wide readers; they do not own or override `reads`.
|
|
142
|
-
- Leave `reads` omitted for
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
150
|
+
- Leave `reads` omitted for default workspace context and `typeAware` off
|
|
151
|
+
unless the user explicitly chooses type-aware execution. `reads: []` omits
|
|
152
|
+
workspace context, not native maps. Only replace `reads` if the user chooses
|
|
153
|
+
to limit workspace context. If requested type awareness lacks compiler resources,
|
|
154
|
+
use the package launcher or a checkout; do not silently turn it off.
|
|
146
155
|
- Install chosen shared rules: `adhere install org/repo/<id>` for each, or
|
|
147
156
|
`adhere install org/repo` for all of them. They land in `.adhere/rules/org/repo/`.
|
|
148
157
|
- Add `exclude` globs for generated or vendored code the default skips miss.
|
|
@@ -177,19 +186,21 @@ cost, and request splits may be higher. Source reload/hash work is bounded to
|
|
|
177
186
|
for execution; if normalized code or ignore
|
|
178
187
|
directives changed since planning, rerun rather than using the old plan.
|
|
179
188
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
scopes from files outside the audit filter.
|
|
183
|
-
tokens than fixed-line excerpts
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
this file's matched literal
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
189
|
+
If the user opts into type awareness, explain that both compiler type/docs
|
|
190
|
+
strings and outgoing declaration snippets add source/documentation sharing and
|
|
191
|
+
token cost, including complete scopes from files outside the audit filter.
|
|
192
|
+
Whole declaration bodies can use more tokens than fixed-line excerpts. Context
|
|
193
|
+
overflow gets one retry without `references`, keeping target code and `symbols`
|
|
194
|
+
intact; it can still overflow and skip the file. Declaration bodies are not
|
|
195
|
+
shortened to fit. Compiler documentation and JSDoc tags can remain even when
|
|
196
|
+
ordinary code comments are stripped, subject to the configured symbol limits.
|
|
197
|
+
The global workspace catalog is not sent: only this file's matched literal
|
|
198
|
+
imports appear under canonical package keys.
|
|
199
|
+
Offer type awareness only as an explicit opt-in, or `reads: []` with type
|
|
200
|
+
awareness off for code alone; never apply either silently. Neither `reads`,
|
|
201
|
+
`typeAware`, nor dependency/shared-context changes invalidate cached judgments.
|
|
202
|
+
If they want fresh answers under changed context, **Ask** before clearing
|
|
203
|
+
`.adhere/cache/`; do not clear it automatically.
|
|
193
204
|
|
|
194
205
|
On a large repo, offer a subtree such as `--filter 'src/**'`, or a file cap
|
|
195
206
|
such as `--limit 100`: the first 100 files needing requests in path order, with
|
|
@@ -201,7 +212,9 @@ or HTTP-size skips after selection consume a slot without runtime refill.
|
|
|
201
212
|
|
|
202
213
|
Explain that a file cap is not an HTTP-request or token/cost cap: each file can
|
|
203
214
|
produce judge, locate, split-batch, and private hook requests. **Ask** before
|
|
204
|
-
sending, then run the command below with only the user's chosen filter/file cap
|
|
215
|
+
sending, then run the command below with only the user's chosen filter/file cap
|
|
216
|
+
and `--type-aware` if they explicitly opted in, or retain `typeAware: true` in
|
|
217
|
+
their config:
|
|
205
218
|
|
|
206
219
|
```sh
|
|
207
220
|
adhere lint --yes
|
|
@@ -209,11 +222,14 @@ adhere lint --yes
|
|
|
209
222
|
|
|
210
223
|
`SourceReads.prepare(paths)` registers eligible-path metadata only, with no
|
|
211
224
|
file I/O, compiler/SDK import, spawn, snapshot, or semantic query, even for a large list.
|
|
212
|
-
Only after confirmation do pending judgments
|
|
213
|
-
location trigger actual per-file native reads
|
|
225
|
+
Only with type awareness enabled, and after confirmation, do pending judgments
|
|
226
|
+
or cached findings still needing location trigger actual per-file native reads
|
|
227
|
+
just before judge/locate. Native
|
|
214
228
|
transactions are serial through one permit; HTTP execution remains concurrent
|
|
215
229
|
at 8. Returned context is reused locally and full budgets are enforced before
|
|
216
|
-
HTTP
|
|
230
|
+
HTTP. Oversized context gets one retry without references when present, then
|
|
231
|
+
skips the file if it still does not fit; code and declaration bodies are not
|
|
232
|
+
shortened to fit. Shared state plus
|
|
217
233
|
one question must fit 32k tokens and state plus all questions must fit 64k per
|
|
218
234
|
request, with 1k reserved for overhead. The SDK may still parse a full selected
|
|
219
235
|
project, and additional monorepo programs may increase startup time and memory.
|
|
@@ -223,9 +239,13 @@ blocks for same-name binding/narrowing contexts, with compiler documentation
|
|
|
223
239
|
and JSDoc tags once per canonical symbol per file. It does not promise literal
|
|
224
240
|
IDE labels or selected-call overload presentation. Symbol/type queries are
|
|
225
241
|
batched, and independent SDK requests are chunked to at most 8 within the single
|
|
226
|
-
active native document/snapshot; HTTP work remains concurrent at 8.
|
|
227
|
-
|
|
228
|
-
|
|
242
|
+
active native document/snapshot; HTTP work remains concurrent at 8. Standard-library
|
|
243
|
+
and Node/Bun built-ins are omitted, but project and third-party names remain.
|
|
244
|
+
`references` is a flat `Record<string, string>` keyed by
|
|
245
|
+
`symbol:repository-relative pathname`, retaining import alias names and original
|
|
246
|
+
pathname casing. Values are declarations of symbols used by the target code,
|
|
247
|
+
not incoming call sites, selecting the smallest complete AST scope without extra
|
|
248
|
+
surrounding lines. Functions include full bodies; arrow/object initializer variables include
|
|
229
249
|
whole variable statements with `export const` and semicolons. Methods, getters,
|
|
230
250
|
and setters include their whole member, not the entire class; classes,
|
|
231
251
|
interfaces, and type aliases include the whole declaration. Repeated/overlapping
|
|
@@ -235,7 +255,10 @@ not automatically expanded. Scopes preserve indentation and the comment/directiv
|
|
|
235
255
|
policy, including associated JSDoc when `includeComments` is true; compiler
|
|
236
256
|
docs/tags in `symbols` remain available regardless. Current-file, declaration-file, `node_modules`, and
|
|
237
257
|
outside-root exclusions are unchanged. There are no incoming callers, counts, structured locations,
|
|
238
|
-
unresolved lists, full-file collection, or completeness markers.
|
|
258
|
+
unresolved lists, full-file collection, or completeness markers. Enabled context
|
|
259
|
+
maps include a self-describing `__comment`; top-level guidance identifies only
|
|
260
|
+
`code` as the audit target. Both native maps require the same type-awareness
|
|
261
|
+
opt-in; `reads` cannot select or disable them individually.
|
|
239
262
|
|
|
240
263
|
The first actual read lazily starts one native TypeScript LSP process with its
|
|
241
264
|
public SDK API pipe; both are pinned to exactly `7.1.0-dev.20261009.1` and must
|
|
@@ -332,15 +355,16 @@ jobs:
|
|
|
332
355
|
Pin the versions the repo already uses: bun's `bun-version`, Node's
|
|
333
356
|
`node-version` from `.nvmrc` or `engines`, and pnpm's from `packageManager`,
|
|
334
357
|
which `pnpm/action-setup` reads. Keep optional dependencies enabled so adhere's
|
|
335
|
-
platform package and its compiler dependency are installed.
|
|
336
|
-
configs and dependencies supply configured context when available;
|
|
337
|
-
no configured project or excluded from one use inferred context. Do not
|
|
338
|
-
or generate a root `tsconfig.json` merely to make default lint run.
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
chose
|
|
342
|
-
|
|
343
|
-
|
|
358
|
+
platform package and its compiler dependency are installed. For type-aware audits,
|
|
359
|
+
existing project configs and dependencies supply configured context when available;
|
|
360
|
+
files with no configured project or excluded from one use inferred context. Do not
|
|
361
|
+
require or generate a root `tsconfig.json` merely to make default lint run. Both
|
|
362
|
+
package launchers and raw executables support the default compiler-free audit,
|
|
363
|
+
including in repos without a `package.json`; no `reads` override is required.
|
|
364
|
+
If the user explicitly chose type-aware execution, use the package launcher or a
|
|
365
|
+
checkout; do not silently turn it off. For the default compiler-free audit, you can
|
|
366
|
+
instead skip runtime setup/install and fetch the raw executable at the version
|
|
367
|
+
the user ran:
|
|
344
368
|
|
|
345
369
|
```yaml
|
|
346
370
|
- run: |
|