Repository navigation
feat(config): AI calls, stop pricing, workflow policy and doctor follow every member setting level (#1459) - #1477
Conversation
403ef86 to
651ad77
Compare
The PR description includes sufficient post-build real-CLI verification; no testing blocker. Review was read-only—nothing from the PR was run, built, or installed. |
|
All five are real, and all five sit in code from #1474, which this PR is stacked on. I'm leaving them there for now.
Each finding, checked against the source:
Fixing them in this stacked PR would edit #1474's function while it is still under review. The PR description lists the first two under "Left to #1474". If #1474 merges without these fixes, I'll fix all five here. |
aeab76d to
68c88e6
Compare
|
All five earlier findings remain unresolved in the specified diff:
No additional confident findings. The PR description includes sufficient post-build real-CLI verification; there is no testing blocker. Review was read-only: nothing from the PR was run, built, or installed. |
|
These are the same five findings as before. They are still in #1474's #1474 has been asked to fix them as part of its rebase onto main: #1474 (comment). I'll rebase this PR on #1474's fixed head. As I said in #1477 (comment), if #1474 merges without them, I'll fix them here. |
@hz89Dev main is red: |
68c88e6 to
e90214d
Compare
|
The earlier usage-reporting finding is resolved:
No additional confident findings. The PR description includes sufficient post-build real-CLI verification; there is no testing blocker. Review was read-only: nothing from the PR was run, built, or installed. |
@hz89Dev #1483 is merged: |
e90214d to
5d6accd
Compare
|
All five earlier findings are resolved in the specified diff.
The PR description includes sufficient post-build real-CLI verification; there is no testing blocker. Review was read-only: nothing from the PR was run, built, or installed. |
|
Confirmed by reading the code: Both lines come from #1474 ( |
5d6accd to
de9becc
Compare
|
The first five earlier findings are resolved. The dotted-alias finding remains; one additional omission is present:
The PR description includes sufficient post-build real-CLI verification; there is no testing blocker. Review was read-only: nothing from the PR was run, built, or installed. |
|
Both are real, and both are in #1474's
I listed both in this PR's description as left to #1474. If #1474 merges without them, I'll fix them here. |
de9becc to
fb21b11
Compare
|
The first five findings and the literal dotted-map-key finding are resolved. The sessions finding remains:
No additional confident findings. The PR description includes sufficient post-build real-CLI verification; there is no testing blocker. Review was read-only: nothing from the PR was run, built, or installed. |
@hz89Dev #1474 is merged (a6fd4a0), with the effective-value, two-team, dotted-name and unused-level fixes. Could you rebase this onto main so it carries only its own commits? Note that a level can now carry |
fb21b11 to
cf26bc0
Compare
|
All earlier findings are resolved, including sessions provenance.
The PR description includes sufficient post-build real-CLI verification; there is no testing blocker. Review was read-only: nothing from the PR was run, built, or installed. |
@hz89Dev Thanks for the rebase. #1491 landed right after it and also edits |
An AI call takes the scope's own ai.tool from the config a load returns, and the machine's from the one reader of machine settings, so the overlay replaces the separate ai.tool reader. A scope config here that cannot be read now fails the call instead of falling back to the machine's tool, a message names the level that set the tool, and the pick cache is keyed by the tool named, so a long-lived process sees a setting changed since. Refs Tencent#1459
The dashboard-report hook read modelAliases from the user-scope config, so a workspace's aliases, and the machine's below a workspace, were never used. It now reads the config the dispatcher resolved. Refs Tencent#1459
… agent trusting its Codex hooks
…invalid A bad member setting in ~/.teamai/config.yaml is skipped with a warning and the next level decides. For workflows.allow that would lift a restriction the member set, so a workflow command now fails and names the key, for a wrong-typed value and for a key allow does not know. Refs Tencent#1459
…usage reporting doctor's text output now lists each member setting some level sets, with the level and file that set it and the values of the levels below it, as doctor --json reports them. The usage-reporting note named the scope's own config.yaml whatever set the value; it now names the machine config when the value comes from there. Refs Tencent#1459
… workflows.allow is unknown The check ran only where a command loads the current config, which a command taking a run id skips once it finds the run, so resume, next, report and respond still ran without the restriction. A machine file that is not valid YAML also passed it, and its restrictions with it. Every workflow command now refuses in both cases. Refs Tencent#1459
…r than throw A scope's own member settings are what its load already validated. Parsing them again with the member settings schema threw on an empty ai.tool, which the install schema accepts, so doctor failed in user scope.
… read A ~/.teamai/config.yaml with no repo is read for its member settings alone. doctor now names any other key it holds, such as excludedSkills, since no command reads it.
A call takes an optional scope, for a caller that acts for a scope other than its working directory's. The votes judge passes the scope its hook fired in. A scope config that cannot be read now fails the call with a message saying no AI call runs until it is fixed.
Say in the docs where workflows.allow is set.
…e read Its workflows.allow restrictions are as unknown as in a file that cannot be parsed, so workflow commands refuse rather than run without them.
…merges model aliases
…lias rows The report now takes each value in effect from the readers the commands use, and lists one row per model alias. The user-scope fixture loads the same values its file holds, and the alias test expects one line per alias. Refs Tencent#1459
…pace The provenance report gives updatePolicy and autoCompactTokens the user scope's value and file when there is a user install. doctor's text named that file the workspace config. It now names it the user config. Refs Tencent#1459
main now reads a workspace's sessions from ~/.teamai/config.yaml when its own file does not set it. Refs Tencent#1459
The provenance report keeps a workspace's own updatePolicy or autoCompactTokens, marked unused, when the user scope decides it. doctor's text listed it as a lower level that says its value. It now says the value is not used. Refs Tencent#1459
sessions became a member setting after the provenance report's key list was written, so doctor showed no row for it. Each run mode now has one, with the policy publish resolves and the values the workspace, machine, team and default set. The defaults stay in session-policy. Refs Tencent#1459
…kspace sets sessions A workspace's own sessions replaces the machine's whole, so a run mode it leaves unset falls to the team or the default, not to the machine. The report now marks the machine's value unused there, and the text shows it even when the default decides the mode. Refs Tencent#1459
An HTTP team repo keeps no session archive, so publish turns every run mode off whatever a level sets. The report credited that off to the level that set a value. It now reports an http-team level as the source and marks the values the member set unused. Refs Tencent#1459
24b9f35 to
c569f73
Compare
|
All earlier findings are resolved, including HTTP session-publishing provenance. No additional confident findings in the specified diff. The PR description includes sufficient post-build real-CLI verification; there is no testing blocker. Additional provider and agent coverage is explicitly deferred to CI. Review was read-only: nothing from the PR was run, built, or installed. |
SaulMoro
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
Approving at c569f73, the rebase onto main after #1491 (range-diff: only the doctor.test.ts imports changed). With the built CLI, against main:
- stop pricing takes the workspace's
modelAliasesover the machine's (15,000,000 micros here, 3,000,000 on main); - a bad or unparseable machine
workflows.allowrefusesworkflow startand the run-id commands, which main lets through, and a valid value is not refused; - the usage note names the machine file when only the machine sets the value (main names the workspace file);
doctortext and--jsonagree on five fixtures, including a level marked unused, twoscopelevels with a user install deciding, dotted names and an emptyai.tool;- the unread-machine-keys note lists only keys teamai really does not read.
The CI review's HTTP-team sessions.publish attribution reproduced on cf26bc0 and is fixed. 28 new or changed tests fail on main and pass here (886/886, also with a symlinked TMPDIR).
Non-blocking
- [P2 non-blocking] With a user install on another team, the doctor text says "from the team's teamai.yaml" without naming which file (
src/doctor.ts:210). The JSON names it, but a member reading the text would open the workspace team's file. - [P3 nit] Two comments still name the removed
aiToolSettings(src/config.ts:425,src/types.ts:840).
#1459 also asks for the member settings to be declared once, as a schema composed into LocalConfigSchema. They are still declared in both places, so I changed the closing line to "Refs #1459". That item can follow separately.
…ow every member setting level (Tencent#1477) teamai's own AI calls, stop pricing, workflow policy and session policy read each member setting in one order: environment, this scope, this machine, the team. teamai doctor shows each member setting with the level that decides it, its file and the levels below, and names the machine keys teamai does not read. Refs Tencent#1459
Summary
With #1473, a workspace config carries the member settings from
~/.teamai/config.yaml. Several readers still went around that config:ai.toolstraight from files and named~/.teamai/config.yamlwhatever set it.modelAliases.workflows.allowon the machine was skipped, which lifted the restriction.doctorshowed where each setting came from only in--json, and its report (feat(config): show member setting provenance #1474) had no row forsessions, a member setting since fix(config): treat sessions as a member setting so a workspace sees the machine value #1483.Each reader now takes the loaded config of its scope, so every level of #1459 applies to it.
callTool(prompt, { launchedBy, scope? }) - read ai.tool from ~/.teamai/config.yaml and the project file + memberTools(scope ?? config resolved for the working directory) + TEAMAI_AI_TOOL → ai.tool of the scope's own file → ai.tool of the machine + a scope config here that cannot be read → override_invalid, no AI call + votes judge passes its hook's scope dashboard-report on stop - modelAliases of the user-scope config + modelAliases of the dispatcher's config (its entries over the machine's) workflow <every subcommand, run ids included> + machine workflows.allow invalid, or the file unreadable or not YAML → refuse doctor (text) + "Member settings:" block: value in effect, the level that set it, the levels below, + and a value set but not used ("the workspace's auto is not used") + usage-reporting note names the level that set it + names keys of a ~/.teamai/config.yaml with no install that no command reads doctor member settings report (text and --json) + sessions.publish.attended / .unattended: SessionPolicy.publish's value, from + workspace → machine (unused once the workspace sets sessions) → team → default; + an HTTP team repo turns both off, reported as level http-team26 files, +561/-116.
Type of Change
Test Plan
npx tsc --noEmitpassesnpm run lintpassesnpx vitest runpasses. On main4d3d1f15, the 50 affected test files pass locally (1,621 tests),doctor,session-policy,types.test.tsand the recall tests included. CI runs the full suite.New tests:
tool-launch-call(level order, level-named messages, the pick cache following a changed setting, an unreadable workspace config, a caller's scope),votes-judgeandhook-handlers(the judge's scope, stop pricing aliases),workflow-commands(a bad, unknown, unparseable or unreadable machineworkflows.allow, and a run-id command),doctor(the text block, one line per alias, the user config named for a machine-wide setting it decides and the workspace value it leaves unused, thesessions.publishrow of each run mode and a machine value a workspace's ownsessionsleaves unused, an emptyai.toolin user scope, the usage note's level, unread machine keys), andlocal-agent(a settings-onlycodexTrustEnabled: false). #1473'stypes.test.tsnow checks that every local config key is a member setting or an install key, so I dropped my test for that.Real CLI, after
npm run build. The setup has a settings-only~/.teamai/config.yaml, no user-scope install, and two workspaces of a local bare team repo whoseteamai.yamlturns recall off. FakecodexandclaudeonPATHlog each launch.Record (macOS, Node 24)
Not run here: other providers (
gitlab,github) and agents (Codex, CodeBuddy, OpenCode). I left those to CI.Related Issues
Refs #1459, together with #1473 and #1474 (both merged). The "declared once" item of #1459 stays open.
Notes for Reviewers
doctor's member settings report. Six commits here follow or extend it:scopelevel that carries~/.teamai/config.yamlin a workspace is the user scope deciding a machine-wide setting, so the text names it "the user config", not "the workspace config".used: falsereads "the workspace's auto is not used", not "the workspace says auto".sessions.publish.attendedand.unattendedrows. The effective value comes fromSessionPolicy.publish, and each level's value fromSessionPolicy.readPublish, so a value publishing ignores never shows as the winner. The defaults moved intoSessionPolicy.publishDefaultsso doctor reads them rather than copying them.sessionsreplaces the machine's whole, so the machine's value for a mode the workspace leaves unset is marked unused, and the mode falls to the team or the default.SessionPolicy.publishturns both modes off. The report names a newhttp-teamlevel as the source and marks the values the member set unused.codexTrustEnabledfor the local agent the same way this branch did, so I dropped my change and kept only its test.sessions. fix(config): treat sessions as a member setting so a workspace sees the machine value #1483 made it a member setting on main, so I dropped my commit that kept it with its install, and listed it among the member settings in the docs.workflows.allow. feat(config): overlay member settings across workspace scopes #1473 now reads an invalid value as the restrictive one. This PR still refuses before that, with a message naming the file, and also when the file cannot be read or parsed, which feat(config): overlay member settings across workspace scopes #1473's reader treats as no settings.override_invalidwhen the scope config, or the.git, in its working directory cannot be read.ci extract-mr, the one call that runs withoutinit, used to fall back to the machine's tool in a checkout whose.gitgit refuses (dubious ownership in some CI containers). It now fails there.not_initialized, the codeloadConfiginworkflow-commands.tsalready gives every config that cannot be loaded. A new code would change what drivers read.